같은 애플리케이션인데 로컬에서는 소스를 마운트하고 디버그 포트를 열고 싶고, 운영에서는 이미지만 쓰고 포트를 닫고 싶을 때가 있습니다. 매번 docker-compose.yml을 손으로 고치는 대신, Compose의 override 병합 기능을 쓰면 베이스 설정 위에 환경별 차이만 얹을 수 있습니다.
자동 병합 규칙
docker compose up은 같은 디렉터리에 docker-compose.yml과 docker-compose.override.yml이 둘 다 있으면 자동으로 둘을 병합합니다. 베이스가 공통 설정을, override가 로컬 전용 차이를 담습니다.
# 두 파일이 어떻게 합쳐졌는지 최종 설정 확인
docker compose config
docker compose config는 실제로 적용될 병합 결과를 출력하므로, 의도대로 합쳐졌는지 확인하는 가장 빠른 방법입니다.
병합이 일어나는 방식
| 값 종류 | 병합 방식 |
|---|---|
스칼라(image, environment 단일 키) | override가 베이스를 덮어씀 |
리스트(ports, volumes) | 두 파일의 항목이 합쳐짐(append) |
맵(environment 맵 형태, labels) | 키 단위로 병합, 같은 키는 덮어씀 |
리스트가 합쳐진다는 점이 함정입니다. 베이스에 ports가 있으면 override의 포트가 추가될 뿐 사라지지 않으니, 운영용 분리는 override가 아니라 별도 파일로 빼는 편이 안전합니다.
환경별 파일 조합
docker-compose.override.yml은 개발용으로 두고, 운영은 명시적으로 파일을 지정합니다.
# docker-compose.yml (베이스)
services:
web:
image: myapp:latest
environment:
- NODE_ENV=production
# docker-compose.override.yml (로컬 자동 적용)
services:
web:
build: .
volumes:
- ./src:/app/src
environment:
- NODE_ENV=development
ports:
- "3000:3000"
# 로컬: override 자동 병합
docker compose up
# 운영: override를 빼고 prod 파일만 명시
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
-f를 직접 지정하면 자동 override는 적용되지 않습니다. 즉 운영에서는 override.yml이 절대 끼어들지 않으므로 로컬 마운트나 디버그 포트가 새어 나갈 일이 없습니다.
체크리스트
docker compose config # 병합 결과가 의도대로인가
docker compose -f a.yml -f b.yml config # 명시 조합 검증
docker compose config | grep -A3 ports # 포트가 의도치 않게 합쳐졌나
배포 전에 항상 docker compose config로 최종 병합본을 확인하세요. 리스트가 합쳐지는 규칙 때문에 로컬 포트가 운영에 섞이는 사고가 가장 흔합니다.
여러 compose 파일을 직접 조합하며 병합 결과를 config로 확인하는 실습은 도커 트랙에서 무료로 할 수 있습니다.