볼륨·네트워크·컴포즈 · 데이터 영속화 · 이론
데이터는 컨테이너보다 오래 살아야 한다
한 줄 요약
컨테이너 쓰기 레이어는 컨테이너와 함께 죽습니다. 오래 살아야 하는
데이터는 볼륨이나 바인드 마운트로 컨테이너 밖에 두어야 합니다.
왜 이게 필요했나
컨테이너를 재배포했더니 업로드 파일이 전부 사라졌다는 신고는 지금도
흔합니다. 원인은 버그가 아니라 설계입니다. 쓰기 레이어는 컨테이너 객체에
붙어 있고, 컨테이너를 지우면 그 레이어도 함께 사라집니다.
여기에 성능 문제가 겹칩니다. 아래 레이어의 파일을 고치려면 위 레이어로
통째로 복사해야 하는데(copy-up), 데이터베이스 파일처럼 큰 파일에는 매우
불리합니다. 그래서 대용량 쓰기는 반드시 볼륨으로 빼라는 말이 관용구가
됐습니다.
어떻게 동작하나
세 가지 방식이 있고 성격이 다릅니다.
| 항목 | 바인드 마운트 | 이름 있는 볼륨 | tmpfs |
| --- | --- | --- | --- |
| 위치 | 호스트 경로를 직접 지정 | 런타임이 관리 | 메모리 |
| 지속성 | 호스트에 영구 | 볼륨에 영구 | 종료 시 소멸 |
| 이식성 | 낮음(경로 의존) | 높음 | 높음 |
| 백업 | 직접 관리 | 전용 명령 | 불가 |
| 주 용도 | 설정 파일, 개발 중 소스 | DB 데이터, 업로드 | 임시 파일, 시크릿 |
문법도 두 가지입니다. 짧은 -v source:target:opts 와 명시적인--mount type=...,source=...,target=...,readonly 인데, 후자는 옵션 이름이
드러나서 리뷰에서 오해가 적습니다.
읽기 전용 마운트는 생각보다 중요합니다. 설정 파일을 :ro 로 붙이면
컨테이너가 실수로든 침해로든 설정을 고칠 수 없습니다. 애플리케이션이
쓰기를 시도하면 Read-only file system 오류가 나고, 이 오류는 곧
"이 컨테이너가 쓰면 안 되는 곳에 쓰려 하고 있다"는 신호입니다.
현장에서 만나는 모습
백업 패턴은 관용구처럼 굳어 있습니다. 볼륨과 백업 디렉터리를 동시에
마운트한 임시 컨테이너를 띄워 아카이브를 만듭니다.
docker run --rm -v dk-data:/source:ro -v /root/backup:/backup alpine:3.20 tar czf /backup/dk-data.tgz -C /source .-C 로 소스 디렉터리 안으로 들어가 상대 경로로 담는 것이 핵심입니다.
이렇게 해야 복원할 때 경로가 어긋나지 않습니다.
rootless 환경에서는 소유권 문제가 자주 생깁니다. 호스트와 컨테이너의 UID
매핑이 달라서인데, 이때는 파일을 chmod 777 로 여는 대신 **매핑을 이해하고
맞추는 쪽**이 옳습니다. 권한을 열어 두면 그 컨테이너뿐 아니라 같은 호스트의
다른 프로세스에게도 열어 주는 것이기 때문입니다.
다음 실습에서 할 것
볼륨을 만들어 쓰고, 컨테이너를 지워도 데이터가 남는지 확인하고, 읽기 전용
마운트의 오류 메시지를 직접 만들어 본 뒤, 백업과 복원을 왕복합니다.