🚀 강의 목표
- Docker 컨테이너가 일회성(Ephemeral) 저장소 구조를 갖는 이유를 이해하고, 이를 보완하는 **볼륨(Volume)**의 개념을 배웁니다.
- **바인드 마운트(Bind Mount)**와 볼륨(Volume)을 비교하여 상황에 맞는 방식을 선택할 수 있습니다.
- 실제 DB 컨테이너(MySQL)를 예시로 들어 데이터 영속성을 유지하는 과정을 실습합니다.
- 실습 과정에서 발생할 수 있는 문제점을 Tip 형태로 중간중간 해결합니다.
🧐 왜 Docker 볼륨이 필요한가?
1. 컨테이너의 일회성 저장소 구조
기본적으로 Docker 컨테이너 내부에 저장되는 데이터는 컨테이너가 제거되면 함께 사라집니다. 예를 들어, 로그 파일이나 DB 데이터가 컨테이너 내부에만 저장되어 있었다면, 컨테이너를 삭제하거나 새로운 버전으로 재배포하는 순간 그 데이터는 유실됩니다.
Tip: 컨테이너 삭제로 인한 데이터 유실
컨테이너를 docker rm 명령어로 제거하면, 컨테이너 내부 파일시스템도 함께 삭제됩니다.
따라서 로그, DB 등 중요한 데이터는 항상 볼륨 또는 바인드 마운트를 통해 보존해야 합니다.
2. 영속성(Persistence) 확보
개발/운영 환경에서 데이터 영속성은 매우 중요합니다. 다음과 같은 경우를 생각해 봅시다.
- MySQL 컨테이너를 구동 중인데, 재배포로 컨테이너가 교체되면 기존 DB 데이터가 날아가면 안 됩니다.
- 애플리케이션 로그, 업로드된 파일, 캐시 등은 재배포 후에도 유지되어야 합니다.
Docker는 이런 문제를 해결하기 위해 **볼륨(Volume)**과 바인드 마운트(Bind Mount) 기법을 제공합니다.
🖥️ Docker 볼륨(Volume) 기초
1. 볼륨의 정의와 특징
- Docker 관리 영역: 볼륨은 호스트의 특정 경로에 생성되지만, 사용자가 명시적으로 그 경로를 지정하지 않아도 됩니다. Docker가 내부적으로 관리합니다.
- 생애주기: 컨테이너와 별도로 존재하기 때문에, 컨테이너가 지워져도 볼륨은 남아 있습니다.
- 공유 및 재사용: 여러 컨테이너가 동일한 볼륨을 참조하여 데이터를 공유할 수 있습니다.
Tip: 볼륨 위치 확인
docker volume inspect <볼륨이름> 명령을 사용하면, 호스트 OS의 어느 경로에 실제 볼륨 데이터가 저장되는지 확인할 수 있습니다.
예: /var/lib/docker/volumes/my-volume/_data 형태로 표시될 수 있습니다.
2. 볼륨 생성 및 마운트
2.1 볼륨 생성
docker volume create my-volume
- my-volume 이라는 이름의 볼륨이 생성됩니다.
2.2 볼륨 마운트
Nginx 예시:
docker run -d \
--name my-nginx \
-p 8080:80 \
-v my-volume:/usr/share/nginx/html \
nginx
- -v my-volume:/usr/share/nginx/html 옵션은
- 왼쪽: Docker 볼륨 이름
- 오른쪽: 컨테이너 내부 경로
이렇게 연결하면, 컨테이너가 삭제되어도 /usr/share/nginx/html 내부에 저장된 데이터는 my-volume에 보존됩니다.
Tip: 볼륨과 컨테이너를 이어주는 순간 생성
만약 my-volume이 존재하지 않았다면, -v my-volume:/경로로 실행할 때 Docker가 자동으로 볼륨을 생성합니다. 하지만 가끔 볼륨명이 헷갈려서 생기는 문제를 방지하려면, 명시적으로 볼륨을 먼저 만들고 실행하는 것을 권장합니다.
🔗 바인드 마운트(Bind Mount) vs 볼륨(Volume)
Docker는 볼륨 외에도 바인드 마운트(Bind Mount) 방식을 제공합니다.
1. 바인드 마운트(Bind Mount)
- 호스트 디렉터리를 그대로 연결:
docker run -d \ --name my-nginx-bind \ -p 8081:80 \ -v /Users/username/web:/usr/share/nginx/html \ nginx
- 호스트의 /Users/username/web 폴더를 컨테이너의 /usr/share/nginx/html와 바로 연결.
- 장점:
- 호스트 파일 변경이 컨테이너 안에 즉시 반영 (개발 환경에서 매우 편리).
- 개발자가 디렉터리 구조를 잘 알고 있으면 설정이 간단.
- 단점:
- 컨테이너 이동성(Portability)이 떨어짐. 호스트 경로가 달라지면 마운트 설정도 수정해야 함.
- 권한 문제가 발생하기 쉽다. 호스트 OS(예: macOS, Windows, Linux)마다 권한 체계가 다르고, 컨테이너 내부 유저와 엇갈릴 수 있음.
Tip: 바인드 마운트 권한 오류
Windows나 macOS에서 호스트 디렉터리를 마운트했는데, 컨테이너 내부에서 Permission Denied가 발생할 수 있습니다.
- 해결책:
- 컨테이너 내부에서 chmod로 권한 변경.
- Docker Desktop 설정에서 파일 공유 옵션을 조정.
- Dockerfile에서 USER를 루트(또는 맞는 권한)로 설정.
2. 볼륨(Volume)
- Docker가 관리하는 추상화된 저장소를 사용합니다.
- 장점:
- 컨테이너 간편 이동. 어떤 환경에서든지 볼륨 이름만 같으면 동일 기능 보장.
- Docker CLI/API로 관리가 쉬우며, 권한 충돌이 적음.
- 프로덕션 환경에서 데이터 보존에 적합.
- 단점:
- 호스트 OS 디렉터리 구조와 직접 연결이 어려움 (개발 시 실시간 변경 반영은 바인드 마운트가 유리).
- 호스트 디렉터리가 어디인지 직관적으로 알기 어려움 (docker volume inspect해야 알 수 있음).
🏃 실습 예제: MySQL 컨테이너를 통한 데이터 영속성
1. 볼륨 생성
docker volume create mysql-data
2. MySQL 컨테이너 실행
docker run -d \
--name mysql-container \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-v mysql-data:/var/lib/mysql \
-p 3306:3306 \
mysql:5.7
- -v mysql-data:/var/lib/mysql: MySQL의 내부 데이터 디렉터리를 mysql-data 볼륨으로 연결합니다.
- -e MYSQL_ROOT_PASSWORD: 루트 계정 비밀번호 설정.
Tip: MySQL 초기 설정 충돌
이미 같은 이름의 볼륨이 있고, 그 볼륨이 다른 DB 데이터를 담고 있다면 MySQL 초기화 과정에서 충돌할 수 있습니다.
- 해결책: 기존 볼륨을 삭제하고 새로 생성하거나, 별도의 볼륨 이름을 사용하세요.
3. 데이터 영속성 테스트
- DB 생성
docker exec -it mysql-container mysql -u root -p # 비밀번호: my-secret-pw CREATE DATABASE test_db;
- 컨테이너 중지 및 삭제
docker stop mysql-container docker rm mysql-container
- 동일 볼륨으로 컨테이너 재실행
docker run -d \ --name mysql-container \ -e MYSQL_ROOT_PASSWORD=my-secret-pw \ -v mysql-data:/var/lib/mysql \ -p 3306:3306 \ mysql:5.7
- DB 확인
docker exec -it mysql-container mysql -u root -p SHOW DATABASES;
- test_db가 남아 있다면 데이터 영속성이 제대로 작동한 것입니다. 🎉
Tip: MySQL 컨테이너 재시작 시 포트 충돌
이미 다른 MySQL 컨테이너가 3306 포트를 점유하고 있다면, 포트 할당 오류가 날 수 있습니다.
- 해결책: 기존 컨테이너 중지, 혹은 -p 3307:3306처럼 다른 포트 사용.
📦 Docker Compose를 활용한 볼륨 관리
Docker Compose를 쓰면 더 직관적으로 볼륨과 컨테이너 설정을 한 번에 관리할 수 있습니다.
docker-compose.yml 예시
version: "3.8"
services:
db:
image: mysql:5.7
container_name: mysql-compose
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
# Docker가 관리하는 볼륨
driver: local
- Compose 실행
docker-compose up -d
- 볼륨 확인
docker volume ls
- docker-compose.yml에서 정의한 mysql-data 볼륨이 생성됨.
Tip: 서비스별 볼륨 중첩 주의
여러 서비스를 하나의 볼륨을 공유하거나, 동일 경로를 서로 다른 볼륨과 바인드 마운트로 중첩 설정하면 예기치 못한 충돌이 발생할 수 있습니다.
항상 docker-compose.yml을 점검하여 중복 설정이 없는지 확인하세요.
📝 정리
- 볼륨(Volume)과 바인드 마운트(Bind Mount)
- 개발 시 바인드 마운트는 코드 수정 → 컨테이너 실시간 반영이 편리.
- 프로덕션 시 볼륨은 Docker가 안전하게 관리하므로 주로 사용.
- 데이터 영속성
- 컨테이너 자체는 삭제되더라도, 볼륨 또는 바인드 마운트로 보존되는 데이터는 유지됨.
- DB, 로그, 업로드 파일 등 중요한 데이터는 반드시 이 방법으로 관리해야 함.
- 에러 및 충돌 해결
- 권한 문제, 포트 충돌, 볼륨 중첩, 초기화 충돌 등을 Tip에서 소개한 방법으로 해결할 수 있음.
- Docker Compose로 여러 컨테이너 환경을 구축하면 더욱 명확하게 의존성을 관리할 수 있음.
🎯 다음 강의 예고
다음 강의에서는 Docker Compose를 활용한 멀티 컨테이너 환경 구성을 좀 더 깊게 파고듭니다.
- 여러 서비스를 동시에 정의하고 실행하는 방법 (예: 웹, DB, 캐시 등).
- 의존성 설정, 환경 변수 관리, 스케일링 기초.
- CI/CD 관점에서 Docker Compose 사용 시 주의사항.
데이터 관리는 이제 OK! 다음은 여러 컨테이너를 유기적으로 연결해보겠습니다. 😊
더 알아보기: Docker 공식 문서 - Volumes
다음 강의에서 만나요! 🐳
'소프트웨어 개발 > Docker' 카테고리의 다른 글
🐳 Docker 강의 8강: Docker Swarm 기본 클러스터링 (0) | 2025.01.27 |
---|---|
🐳 Docker 강의 7강: Docker 배포 전략 – 이미지 최적화와 Private Registry 활용 (0) | 2025.01.27 |
🐳 Docker 강의 6강: Docker Compose를 활용한 멀티 컨테이너 환경 구성 (0) | 2025.01.27 |
🐳 Docker 강의 4강: Docker 네트워킹 (0) | 2025.01.27 |
🐳 Docker 강의 2강: Docker 이미지와 컨테이너 기본 사용법 (0) | 2025.01.27 |