Docker Volumes vs Bind Mount vs Named Volume

도커를 쓰다 보면 이런 의문이 생깁니다
목차
Docker Volumes 이 뭐야?
“컨테이너를 삭제했는데, 내 DB도 같이 사라졌네?”
“volumes를 썼는데 bind mount랑 뭐가 다른 거야?”
“영구 저장하려면 어떤 걸 써야 해?”
오늘은 이 3가지 저장 방식의 차이를 그림과 코드로 확실하게 정리합니다.
세 가지 저장 방식의 정체
| 유형 | 예시 | 저장 위치 | 설명 |
|---|---|---|---|
| Bind Mount | ./html:/usr/share/nginx/html | 내 PC(Host) 폴더 | 개발 환경에서 가장 흔히 사용. 로컬 ↔ 컨테이너 실시간 연동 |
| Named Volume | mydata:/var/lib/mysql | 도커 내부(var/lib/docker/volumes/) | 도커가 직접 관리하는 영구 저장소 |
| Anonymous Volume | /var/lib/mysql (이름 없음) | 도커 내부 | 컨테이너 삭제 시 자동 삭제 (임시 데이터용) |
Bind Mount — 개발용 로컬 연동
예시
volumes:
- ./html:/usr/share/nginx/html
특징
- 내 로컬 폴더(
./html)와 컨테이너 내부 폴더(/usr/share/nginx/html)를 연결 - 코드 수정 즉시 반영
- Git으로 버전 관리 가능
- 컨테이너를 삭제해도 로컬 파일은 유지
단점
- 권한 문제 발생 가능 (특히 Windows ↔ Linux)
- 로컬 환경 의존성 높음 (서버 배포 시 비추천)
Named Volume — 운영 환경의 표준
📄 예시
volumes:
- mydata:/var/lib/mysql
volumes:
mydata:
특징
- 도커가
/var/lib/docker/volumes/mydata/_data내부에 자동 생성 - 컨테이너 삭제해도 데이터 유지
- 경로 대신 “이름”으로 관리하기 때문에 마이그레이션 편함
- Docker Desktop → Volumes 탭에서 시각적으로 확인 가능
위치 확인
docker volume inspect mydata
결과:
{
"Mountpoint": "/var/lib/docker/volumes/mydata/_data"
}
여기서 _data 폴더가 실제 파일 저장 위치입니다.
Anonymous Volume — 이름 없는 임시 저장소
📄 예시
volumes:
- /var/lib/mysql
특징
- 컨테이너 실행 시마다 랜덤 이름으로 생성
- 컨테이너 삭제 시 자동 삭제됨
- 임시 캐시나 테스트 데이터용
단점
- 나중에 찾을 수 없음
- 실무에서는 거의 사용하지 않음
비교 표 한눈에 보기
| 구분 | Bind Mount | Named Volume | Anonymous Volume |
|---|---|---|---|
| 경로 형태 | ./html:/usr/... | mydata:/usr/... | /usr/... |
| 저장 위치 | 내 PC (프로젝트 폴더) | 도커 내부 /var/lib/docker/volumes/ | 도커 내부 (임시) |
| 데이터 유지 | 로컬 파일 그대로 유지 | 컨테이너 삭제해도 유지 | 컨테이너 삭제 시 삭제 |
| 실시간 반영 | ✅ 즉시 반영 | ❌ 반영 안 됨 | ❌ 반영 안 됨 |
| 주 사용 목적 | 개발 환경 | 운영·배포 환경 | 임시 테스트 |
| 백업 편의성 | Git 가능 | docker volume export 필요 | 불가 |
실제 예시로 보는 차이점
docker-compose.yml
version: "3.8"
services:
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: test1234
volumes:
- mydata:/var/lib/mysql
volumes:
mydata:
mydata는 Docker 내부의 /var/lib/docker/volumes/mydata/_data에 저장됩니다.
만약 컨테이너를 삭제해도
docker rm -f db
docker volume ls
여전히 mydata는 남아 있습니다
볼륨 용량 확인 & 정리
# 볼륨 리스트 보기
docker volume ls
# 특정 볼륨 상세 보기
docker volume inspect mydata
# 전체 도커 용량 확인
docker system df
# 사용 안 하는 볼륨 정리
docker volume prune
데이터 백업 / 복원
백업
docker run --rm -v mydata:/data -v $(pwd):/backup busybox tar czf /backup/backup.tar.gz -C /data .
복원
docker run --rm -v mydata:/data -v $(pwd):/backup busybox tar xzf /backup/backup.tar.gz -C /data
이 방식으로 MySQL, WordPress, Redis 등의 데이터를 완벽하게 이전할 수 있습니다.
어떤 걸 써야 할까?
| 상황 | 추천 방식 |
|---|---|
| 개발 환경 (로컬에서 바로 수정) | Bind Mount |
| 운영 서버 (데이터 영구 저장) | Named Volume |
| 테스트나 임시 캐시 데이터 | ⚙️ Anonymous Volume |
마무리
이제 도커의 저장 구조를 명확히 이해했을 겁니다.
Bind Mount→ 내 코드 폴더 실시간 반영Named Volume→ 운영 환경의 안전한 데이터 보존Anonymous Volume→ 임시 데이터용 일회성 볼륨
이 구조를 알면
“컨테이너를 삭제해도 DB는 남는다”
“코드는 즉시 반영되지만 데이터는 분리된다”
라는 도커의 진짜 강점을 실감하게 됩니다.