컨테이너 기술을 익히다 보면 누구나 한 번쯤은 겪는 고민이 있어요
"데이터는 컨테이너에 잘 저장됐는데, 컨테이너를 삭제하니 사라졌어요. 왜죠?"
이런 문제는 Docker의 특성상 너무나 자연스러운 현상이에요. 그리고 이 문제를 깔끔하게 해결해 주는 기능이 바로 Volume입니다.
왜 Volume이 필요할까?
Docker의 컨테이너는 기본적으로 휘발성이에요. 컨테이너 내부에 데이터를 저장해도, 컨테이너가 삭제되면 데이터도 함께 사라져요. 하지만 이런 데이터는 쉽게 날아가면 안 되겠죠?
- 데이터베이스의 사용자 데이터
- 로그 파일
- 사용자가 업로드한 이미지 등 정적 리소스
이런 데이터는 컨테이너의 라이프사이클과는 독립적으로 영구 보존 되어야 해요. 이럴 때 필요한 것이 바로 Volume이에요.
도커 볼륨의 세 가지 방식
방식 | 설명 | 특징 | 예시 |
Volume | Docker가 내부에서 직접 관리 | 영속성 뛰어남, 백업 편리 | 운영 환경의 DB, 앱 데이터 |
Bind Mount | 호스트의 특정 경로를 컨테이너에 연결 | 실시간 반영 가능, 유연성 높음 | 개발 중 코드 공유, 로그 확인 |
tmpfs Mount | 휘발성 메모리 공간에 저장 | 고속 처리, 재부팅 시 데이터 삭제 | 캐시, 인증 정보, 민감한 임시 데이터 |
각 방식은 내부 동작 방식도 다르고, 보안/성능/유연성 측면에서도 큰 차이가 있어요.
1. Volume (Docker Managed Volume)
Docker가 직접 관리하는 특별한 디렉터리(/var/lib/docker/volumes)에 데이터를 저장하는 방식이에요.
docker volume create mydata
docker volume 명령은 Docker root dit(/var/lib/docker) 영역에 volume 영역을 만들어 컨테이너 내부 경로와 연결(mount)합니다.
docker run -d \
-v mydata:/var/lib/mysql \
mysql:8.0
- mydata는 도커가 /var/lib/docker/volumes/mydata/_data에 저장돼요.
- 컨테이너를 삭제해도 mydata 볼륨은 살아 있어서 데이터 유지 가능
- 운영 환경에서 가장 많이 사용하는 방식입니다.
💡 암시적 Volume 생성
docker run \
-v /data \
nginx
- 위처럼 volume 이름을 명시하지 않아도 위처럼 -v some_path만 쓰면 Docker가 자동으로 무작위 이름의 Volume을 생성해요.
- 단점은 이름이 랜덤이라 관리/식별이 불편해요. 때문에 직접 이름을 명시해서 생성하는 습관이 좋아요.
2. Bind Mount (호스트 경로 마운트)
호스트 머신의 디렉터리를 컨테이너에 그대로 연결하는 방식이에요.
docker run --rm \
-v $(pwd)/html:/usr/share/nginx/html \
nginx
- 호스트의 절대 경로:컨테이너 내부 경로를 직접 마운트하여 동기화
- 실시간으로 변경사항 반영돼서 개발에 유용
💡 기본 권한은 rw
- 마운트 시 기본 권한은 읽기/쓰기(rw)예요.
- 필요시 읽기 전용으로 설정할 수도 있어요.(컨테이너가 파일을 수정할 수 없음)
-v $(pwd)/html:/usr/share/nginx/html:ro
3. tmpfs Mount (메모리 기반 휘발성 저장)
디스크를 쓰지 않고, 호스트 메모리(RAM)에 데이터를 저장해요.
docker run --rm \
--tmpfs /app/tmp:rw,size=64m \
myapp
- 컨테이너 내부의 /app/tmp 경로에 64MB 크기의 메모리 기반 파일 시스템을 마운트 하는 명령어
- tmpfs는 리눅스 커널의 메모리 파일 시스템 기능을 활용하고, 컨테이너가 실행될 때 호스트 메모리를 직접 할당해 사용합니다.
- 컨테이너가 종료 시 데이터도 함께 사라짐, 영구 저장이 목적이라면 사용하면 안 돼요.
- 컨테이너 간의 공유 설정은 안되고, Linux 기반 Docker에서만 지원됩니다.
💡 그렇다면 굳이 휘발성인데 tmpfs를 쓸까요?
- 디스크 대신 메모리 기반이기 때문에 빠른 처리가 가능
- 민감한 데이터(세션, 인증 키 등)를 디스크에 남기지 않음
- 캐시, 임시 파일 등 처리 후 바로 삭제해도 무방한 데이터에 적합
🔹 docker volume 예제
1. 실전 예제 1: DB 데이터 유지
docker volume create mysql-data
docker run -d \
--name mysql \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=1 \
mysql:latest
- mysql-data 볼륨은 컨테이너 외부에 데이터 저장
- 컨테이너를 삭제해도 데이터는 살아남음
2. 실전 예제 2: 개발 환경에서 코드 실시간 반영
docker run --rm -p 3000:80 \
-v $(pwd)/my-site:/usr/share/nginx/html \
nginx
- 로컬에서 수정한 코드가 바로 컨테이너에 반영돼요.
- 개발 시 많이 사용되는 워크 플로우
다른 컨테이너의 볼륨 공유하는 법 --volumes-from
--volumes-from은 기존 컨테이너의 볼륨 설정을 그대로 복사해서 재사용하는 기능이에요.
docker run -d \
--name dbdata \
-v /data \
busybox
docker run -it --rm \
--volumes-from dbdata \
ubuntu
- dbdata의 볼륨(/data)을 새로운 컨테이너에서도 동일하게 사용 가능해요.
- 여러 컨테이너가 같은 데이터를 접근해야 할 때 유용해요.