도커 컴포즈
- 4.1 docker-compose.yml 파일
- 4.2 도커 컴포즈 기본 사용법
- 4.3 도커 컴포즈 활용
웹 서버 + DB + 캐시처럼 여러 컨테이너가 필요한 환경을 매번 docker run으로 하나씩 띄우는 건 비현실적이잖아. 도커 컴포즈는 이 문제를 YAML 파일 하나로 해결해.
핵심은 docker-compose.yml(또는 compose.yml) 파일이야. 이 파일에 애플리케이션을 구성하는 모든 서비스, 네트워크, 볼륨을 선언적으로 정의하거든:
version: "3.8"
services:
web:
image: nginx:latest
ports:
- "80:80"
depends_on:
- app
networks:
- frontend
app:
build: ./app
environment:
- DB_HOST=db
- DB_PORT=3306
depends_on:
- db
networks:
- frontend
- backend
db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=secret
volumes:
- db-data:/var/lib/mysql
networks:
- backend
volumes:
db-data:
networks:
frontend:
backend:
주요 설정 항목들을 보면 — image는 사용할 이미지고, build는 Dockerfile로 직접 빌드할 경로야. image와 build를 동시에 쓸 수도 있어. ports는 포트 매핑이고 docker run -p와 같지. environment는 환경 변수 설정인데 .env 파일을 참조하는 것도 가능해. volumes는 데이터 영속성을 위한 볼륨 마운트고, networks는 서비스가 참여할 네트워크야. 같은 네트워크에 있는 서비스끼리만 통신 가능하지. 그리고 depends_on은 서비스 시작 순서를 지정하는 건데, 여기서 주의할 게 있어 — "시작 순서"일 뿐 "준비 완료"를 보장하지는 않아. DB가 시작됐지만 아직 커넥션을 받을 준비가 안 된 상태일 수 있거든. version 필드는 Compose 파일 포맷 버전을 지정하는데, Docker Compose V2부터는 사실상 선택사항이야.
기본 사용법은 간단해:
docker compose up # 포그라운드 실행
docker compose up -d # 백그라운드 실행
docker compose up --build # 이미지 다시 빌드 후 실행
docker compose up은 YAML에 정의된 모든 서비스를 한 번에 생성하고 시작해. 이미지가 없으면 자동으로 빌드하거나 pull 하지.
docker compose stop # 서비스 중지 (컨테이너 유지)
docker compose down # 서비스 중지 + 컨테이너/네트워크 삭제
docker compose down -v # 볼륨까지 삭제
docker compose ps # 서비스 상태 확인
docker compose logs # 전체 로그
docker compose logs -f web # 특정 서비스 실시간 로그
docker compose run app bash # app 서비스로 일회성 명령 실행
docker compose exec app bash # 실행 중인 app 서비스에 접속
run은 새 컨테이너를 만들고, exec은 기존 컨테이너에 접속하는 차이가 있어. 참고로 docker-compose(하이픈)은 V1이고 별도 설치가 필요했어. docker compose(공백)은 V2로 도커에 내장되어 있지. 지금은 V2가 표준이야.
활용 쪽으로 가면, 환경 변수를 .env 파일로 분리할 수 있어:
# .env
DB_PASSWORD=my-secret-pw
services:
db:
environment:
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
env_file 항목으로 별도의 환경 변수 파일을 지정할 수도 있고, 프로덕션과 개발 환경에서 다른 .env 파일을 사용하면 환경별 설정을 깔끔하게 분리할 수 있지. 여러 Compose 파일을 조합하는 것도 가능해:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
기본 설정을 docker-compose.yml에, 환경별 오버라이드를 별도 파일에 정의하는 패턴이야. 개발 환경에서는 소스 코드를 볼륨으로 마운트하고, 프로덕션에서는 빌드된 이미지를 사용하는 식으로 분리할 수 있어.
스케일링도 간단해:
docker compose up -d --scale app=3
app 서비스를 3개로 늘리는 건데, 포트가 충돌하지 않도록 주의해야 해. 호스트 포트를 고정하면 스케일링이 안 되니까, 로드 밸런서를 앞에 두거나 포트를 동적으로 할당해야 하지.
그리고 헬스 체크도 중요해:
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
depends_on만으로는 서비스가 "준비"됐는지 알 수 없으니까, 헬스 체크를 설정하면 서비스의 실제 상태를 확인할 수 있어.
정리
4장 읽고 기억할 거 세 가지:
- docker-compose.yml 하나로 멀티 컨테이너 환경을 정의한다. 서비스, 네트워크, 볼륨을 선언적으로 관리.
docker compose up -d로 시작하고docker compose down으로 정리한다. 환경 변수는.env로 분리하고, 여러 Compose 파일로 환경별 설정을 오버라이드할 수 있다.depends_on은 시작 순서만 보장하지, 준비 완료를 보장하지 않는다. 서비스의 실제 준비 상태를 확인하려면 헬스 체크를 설정해야 한다.