docker rm으로 컨테이너를 지웠더니 DB 데이터가 통째로 날아간 경험이 있다면, 그건 버그가 아니라 도커의 기본 동작입니다. 컨테이너의 쓰기 레이어는 컨테이너와 운명을 같이합니다. 컨테이너가 사라지면 그 안에 쓴 데이터도 사라집니다. 데이터를 살리려면 데이터를 컨테이너 바깥에 두어야 하고, 그 방법이 볼륨과 바인드마운트입니다.
두 가지 방식의 차이
로컬 터미널
# 볼륨 — 도커가 관리하는 저장 공간
docker volume create pgdata
docker run -d -v pgdata:/var/lib/postgresql/data postgres
# 바인드마운트 — 호스트의 특정 경로를 그대로 연결
docker run -d -v /opt/app/config:/etc/app nginx
| 구분 | 볼륨 | 바인드마운트 |
|---|---|---|
| 위치 | 도커가 관리(/var/lib/docker/volumes) | 호스트의 지정 경로 |
| 용도 | DB·앱 영구 데이터 | 소스코드·설정 파일 실시간 반영 |
| 이식성 | 높음(경로 신경 안 씀) | 낮음(호스트 경로에 종속) |
| 추천 | 운영 데이터 저장 | 개발 중 코드 마운트 |
운영 데이터는 볼륨, 개발 중 코드 반영은 바인드마운트가 기본 선택입니다.
데이터가 유실되는 대표 사고
- 마운트 없이 DB를 띄움 —
-v없이docker run postgres로 띄우면 컨테이너 삭제 시 전부 소멸. 데이터 컨테이너는 반드시 볼륨을 건다. - 경로를 잘못 지정 — 컨테이너가 데이터를 쓰는 실제 경로가 아닌 곳에 마운트하면 볼륨은 비어 있고 데이터는 여전히 쓰기 레이어로 감. Postgres는
/var/lib/postgresql/data, MySQL은/var/lib/mysql. docker compose down -v—-v플래그가 붙으면 named volume까지 같이 삭제됩니다. 데이터를 지울 의도가 아니면 그냥down만.- 바인드마운트로 빈 디렉터리를 덮음 — 호스트의 빈 폴더를 컨테이너의 데이터 경로에 마운트하면 컨테이너 안 기존 파일이 가려져 "사라진 것처럼" 보임.
마운트가 실제로 걸렸는지 확인
로컬 터미널
docker volume ls # 볼륨 목록
docker inspect <container> --format '{{json .Mounts}}'
docker exec <container> ls /var/lib/postgresql/data
inspect의 Mounts에 의도한 Source/Destination이 보이는지가 핵심입니다. 컨테이너를 지웠다 다시 띄워도 데이터가 남아 있으면 제대로 된 것입니다.
체크리스트
Docker
docker run -v pgdata:/var/lib/postgresql/data ... # 데이터 경로에 볼륨
docker inspect <container> --format '{{json .Mounts}}'
docker rm <container> && docker run -v pgdata:... # 재기동 후 데이터 잔존 확인
docker compose down # -v 없이! (볼륨 보존)
마운트를 데이터 경로에 정확히 걸고, down -v만 조심하면 데이터 유실은 거의 막힙니다.
볼륨과 바인드마운트를 직접 걸어 보고 컨테이너를 지웠다 살리며 데이터가 남는지 확인하는 실습은 도커 트랙에서 회원가입 없이 무료로 할 수 있습니다.