- 쓰기 레이어 — 컨테이너를 지우면 사라진다. union fs 를 거쳐 느리다
- 볼륨 — 도커가 관리하는 저장소. 권장 방식
- 바인드 마운트 — 호스트 경로를 그대로 연결. 개발에 편하고 운영엔 위험
- tmpfs — 메모리. 디스크에 안 남는다 (비밀 · 임시 파일)
docker volume create appdata
docker run -v appdata:/var/lib/app myapp # 볼륨
docker run -v $(pwd)/src:/src:ro myapp # 바인드 (읽기 전용)
docker run --tmpfs /tmp:rw,size=64m myapp # tmpfs
왜 볼륨이 빠른가
-
볼륨은 union filesystem 을 거치지 않고 호스트 파일시스템에 직접 쓴다
-
copy-up 이 없다
-
DB 파일 · 큰 로그처럼 쓰기가 잦은 데이터에 필수다
-
"컨테이너에서 DB 가 느리다" 의 해결책이 대개 이것이다
마운트가 기존 내용을 가린다
이미지 안 /app/config 에 파일이 있는데 그 경로에 빈 볼륨을 마운트하면?
- 마운트가 위에 덮인다 → 이미지의 파일이 안 보인다
(볼륨이 '처음 비어 있을 때' 는 이미지 내용을 복사해 넣는 동작이 있지만 바인드 마운트는 그렇지 않다 — 그냥 가린다)
"설정 파일이 사라졌다" 의 전형이다
권한 문제
바인드 마운트한 호스트 디렉터리의 소유자와 컨테이너 안 프로세스의 UID 가 다르면 쓰기가 안 된다
- Permission denied
대응
- 컨테이너 UID 를 호스트 소유자와 맞춘다 (--user 1000:1000)
- 호스트 디렉터리 권한을 조정한다
- 볼륨을 쓰면 도커가 초기 권한을 맞춰 주므로 덜 겪는다
USER 로 비루트를 지정한 이미지에서 특히 자주 만난다
운영에서 바인드 마운트를 피하는 이유
- 호스트 경로 구조에 의존하게 된다 (노드마다 달라진다)
- 컨테이너가 호스트 파일을 직접 수정할 수 있다
- 오케스트레이터가 스케줄링을 자유롭게 못 한다
개발에서는 소스 실시간 반영에 편해 널리 쓰지만, 운영에서는 볼륨이나 외부 스토리지로 간다
정리
docker volume ls
docker volume prune # 참조되지 않는 볼륨 삭제 ← 데이터 손실 주의
docker system df -v # 볼륨별 크기
익명 볼륨(이미지의 VOLUME 지시자로 자동 생성된 것)이 쌓이기 쉽다 디스크가 찰 때 확인 대상이다
이름 있는 볼륨 vs 익명 볼륨
-
docker run -v appdata:/data ... 이름 있는 볼륨 — 관리·재사용이 쉽다
-
docker run -v /data ... — 익명 볼륨 — 무작위 이름으로 생성된다
-
이미지의 VOLUME /data — 컨테이너를 만들 때마다 익명 볼륨 생성
-
익명 볼륨은 컨테이너를 지워도 남는다 (docker rm -v 로 함께 지운다)
-
디스크가 차는 원인 중 눈에 잘 안 띄는 것
- docker volume ls 로 이름이 해시인 것들을 확인한다
백업
# 볼륨 내용을 tar 로 빼낸다
docker run --rm -v appdata:/data -v $(pwd):/backup alpine \
tar czf /backup/appdata.tgz -C /data .
# 복원
docker run --rm -v appdata:/data -v $(pwd):/backup alpine \
tar xzf /backup/appdata.tgz -C /data
볼륨은 도커가 관리하지만 백업은 해 주지 않는다 운영 데이터가 볼륨에만 있다면 백업 절차를 별도로 만든다
면접 함정
- ❌ "볼륨과 바인드 마운트는 같다" → 관리 주체와 이식성이 다르다.
- ❌ "마운트하면 기존 파일과 합쳐진다" → 가려진다.