개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

Docker Compose Volumes — 데이터를 영구 저장하는 방법

2025년 7월 27일
DockervolumesNamed VolumeBind Mount데이터 영속성

컨테이너는 기본적으로 휘발성이다. 컨테이너가 삭제되면 내부 파일도 함께 사라진다. 데이터베이스나 업로드 파일처럼 영구 보존이 필요한 데이터는 Volume을 통해 컨테이너 외부에 저장해야 한다. Docker Compose는 이를 선언적으로 관리할 수 있는 깔끔한 방법을 제공한다.

Named Volume vs Bind Mount

두 가지 방식은 데이터를 어디에, 어떻게 저장하느냐에서 차이가 난다.

구분Named VolumeBind Mount
저장 위치Docker가 관리하는 내부 경로호스트의 특정 디렉터리
선언 방식최상위 volumes: 블록 필요호스트 경로를 직접 지정
이식성높음낮음 (경로 의존)
주요 용도DB 데이터, 캐시소스 코드, 설정 파일

Named Volume: Docker Engine이 직접 생성·관리하는 볼륨. docker volume ls로 확인 가능.

Bind Mount: 호스트 파일시스템의 경로를 컨테이너 내부에 직접 연결하는 방식.

최상위 volumes 선언

Named Volume을 사용하려면 compose.yml 최상위에 volumes: 블록을 먼저 선언해야 한다. 이 선언이 없으면 Compose는 해당 볼륨을 인식하지 못한다.

volumes:
  postgres_data:
  redis_cache:

이렇게 선언된 볼륨은 docker volume ls에서 <project>_postgres_data 형태로 확인할 수 있다.

서비스별 마운트 포인트 연결

[Host / Docker Volume]          [Container]
─────────────────────           ─────────────────────
postgres_data (Named Volume) ── /var/lib/postgresql/data
./nginx/conf.d (Bind Mount)  ── /etc/nginx/conf.d  (ro)
./app/src      (Bind Mount)  ── /app/src

각 서비스는 volumes: 키에서 위 볼륨을 마운트한다.

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - postgres_data:/var/lib/postgresql/data

  cache:
    image: redis:7
    volumes:
      - redis_cache:/data

  web:
    image: nginx:alpine
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro

volumes:
  postgres_data:
  redis_cache:

마운트 경로 끝의 :ro는 read-only 옵션이다. 컨테이너가 해당 경로에 쓰기를 시도하면 오류가 발생한다.

데이터베이스 볼륨 예시

PostgreSQL은 데이터 파일을 /var/lib/postgresql/data에 저장한다. Named Volume 없이 컨테이너를 재시작하면 모든 데이터가 초기화된다.

# 볼륨 목록 확인
docker volume ls

# 볼륨 상세 정보 (실제 저장 경로 포함)
docker volume inspect myproject_postgres_data

# 볼륨을 유지하며 컨테이너만 재생성
docker compose up -d --force-recreate db

docker compose down은 컨테이너와 네트워크를 삭제하지만 볼륨은 유지한다. 볼륨까지 삭제하려면 --volumes 플래그를 명시해야 한다.

# 컨테이너 + 볼륨 모두 삭제 (데이터 영구 삭제 주의)
docker compose down --volumes

볼륨 외부 참조 (external)

이미 존재하는 볼륨을 Compose가 새로 생성하지 않고 그대로 사용하게 하려면 external: true를 지정한다.

volumes:
  shared_data:
    external: true

external: true로 선언된 볼륨이 존재하지 않으면 docker compose up 시 오류가 발생한다. 사전에 docker volume create shared_data로 생성해두어야 한다.

Named Volume은 데이터 영속성과 이식성을 동시에 확보하는 가장 안전한 방법이다. Bind Mount는 개발 중 소스 코드 실시간 반영처럼 호스트와 긴밀하게 연동해야 할 때만 선택적으로 사용한다.

← 이전 글Docker Compose Networks — 서비스 간 통신을 설정하는 방법
다음 글 →Docker Compose 환경 변수 — 설정값을 외부에서 주입하는 방법