Docker Volume
Docker Volume은 컨테이너의 라이프사이클과 독립적으로 데이터를 보존하는 저장 메커니즘입니다. 컨테이너는 기본적으로 쓰기 가능한 레이어에 데이터를 저장하지만, 컨테이너가 삭제되면 그 데이터도 함께 사라집니다. 볼륨은 이 문제를 해결해 데이터가 컨테이너 밖에 살도록 만듭니다.
▶아키텍처 다이어그램
🔍 구조 다이어그램점선 애니메이션은 데이터 또는 요청의 흐름 방향을 나타냅니다
컨테이너는 교체를 전제로 쓰기 때문에, 데이터베이스 파일이나 업로드 결과를 컨테이너 안의 writable layer에만 두면 재배포나 재생성 때 함께 사라집니다. 이 writable layer는 이미지 위에 잠깐 덧붙는 쓰기 공간이라 컨테이너 수명과 함께 없어집니다. 여기에 계속 데이터를 쌓으면 영속성도 잃고, 여러 컨테이너가 같은 데이터를 공유하기도 어렵습니다.
컨테이너 기술이 확산되면서 '컨테이너는 상태를 갖지 않아야 한다'는 원칙이 굳어졌습니다. 불변 이미지에서 새 컨테이너를 빠르게 띄우고 버리는 패턴이 배포와 스케일링에 유리했기 때문입니다. 그런데 데이터베이스, 파일 저장소, 캐시처럼 상태를 유지해야 하는 워크로드도 컨테이너로 올라오기 시작했습니다. Docker가 Named Volume을 도입한 것은 컨테이너의 일회성을 깨지 않으면서도 데이터 영속성을 보장하기 위해서였습니다. 이전에는 호스트 디렉터리를 직접 마운트하는 방식만 있었는데, 이는 호스트 경로에 강하게 묶여 이식성이 떨어졌습니다. Named Volume은 Docker 엔진이 관리하는 추상화 계층을 끼워 넣어 이 의존성을 줄였습니다.
일반적인 파일 쓰기는 먼저 컨테이너의 writable layer로 들어갑니다. 볼륨이나 마운트를 붙이면 특정 경로만 이 임시 레이어 밖의 실제 저장소로 우회되므로, 컨테이너를 새로 띄워도 그 경로의 데이터는 남습니다. 볼륨의 핵심은 파일을 컨테이너 안에 오래 두는 것이 아니라, 교체 주기 밖의 저장소에 연결하는 데 있습니다. Named Volume은 Docker가 경로 관리를 맡는 방식이라 운영 환경에서 다시 붙이기 쉽고, 여러 컨테이너가 같은 데이터를 공유할 때도 다루기 편합니다. Bind Mount는 호스트 디렉터리를 그대로 노출하므로 개발 중 소스코드를 바로 반영할 때 유리하지만, 호스트 경로 구조에 강하게 묶입니다. tmpfs는 디스크 대신 메모리에 두는 마운트라 민감한 임시 데이터에는 맞지만 컨테이너가 멈추면 내용도 함께 사라집니다.
Named Volume과 Bind Mount는 둘 다 컨테이너 밖에 데이터를 보존한다는 점에서 같습니다. 차이는 누가 관리하느냐에 있습니다. Named Volume은 Docker가 생성, 경로 관리, 정리까지 담당하므로 이식성이 높고 호스트 디렉터리 구조를 알 필요가 없습니다. Bind Mount는 호스트의 특정 경로를 그대로 노출하기 때문에 개발 환경에서 코드를 바로 반영하기에는 편하지만, 호스트 운영체제와 디렉터리 구조에 묶입니다. 운영 환경에서 데이터 영속성이 목적이면 Named Volume이 안전하고, 개발 중 파일 변경을 실시간으로 확인해야 하면 Bind Mount가 실용적입니다.
데이터베이스 컨테이너를 운영할 때 Named Volume을 붙이면 컨테이너 이미지를 업그레이드하거나 재시작해도 데이터가 보존됩니다. Docker Compose에서 `volumes:` 섹션을 정의해 두면 여러 서비스가 같은 볼륨을 공유하거나 각자의 볼륨을 갖는 구조를 선언적으로 관리할 수 있습니다. 개발 환경에서는 Bind Mount로 로컬 소스 코드를 컨테이너에 연결해 핫 리로드를 구현하는 것이 일반적입니다. 다만 이 패턴을 프로덕션에 그대로 가져가면 호스트 경로 의존성과 권한 문제가 생길 수 있으므로, 배포 환경에서는 Named Volume이나 외부 스토리지 드라이버로 전환하는 편이 안전합니다. 볼륨 백업도 운영 시 빠지기 쉬운 부분인데, `docker volume` 명령이나 별도 백업 컨테이너를 통해 주기적으로 스냅샷을 남겨야 합니다.