도커를 쓰다 보면 웹 서버, DB, 캐시, 메시지 큐 등 컨테이너가 여러 개로 늘어나기 마련입니다.
이때 매번 docker run 명령어를 일일이 치다 보면:
- 설정도 제각각,
- 명령어도 길어지고,
- 환경별(개발/테스트/운영) 관리도 어려워집니다.
이 문제를 해결해 주는 도구가 바로 Docker Compose입니다.docker-compose.yml 한 파일에 멀티 컨테이너 구성·환경·네트워크를 정의하고,docker compose up 한 번으로 서버 전체를 띄울 수 있습니다.
1. Docker Compose란?
Docker Compose는 여러 개의 Docker 컨테이너(서비스)를 YAML 파일(docker-compose.yml) 로 정의하고 묶어서 실행·중지·관리하는 도구입니다.
Docker Compose를 쓰면 좋은 이유
- 설정 일원화: 모든 서비스 설정을 한 파일에 정의
- 명령어 단순화:
docker compose up/down만으로 전체 환경 관리 - 재현성↑: 팀원·서버 어디에서든 동일한 환경 재구축
- 확장성↑:
scale,replicas등으로 컨테이너 수 쉽게 조정 - 환경 분리 용이: dev/staging/prod용 compose 파일 분리
2. Docker Compose 설치 & 기본 명령어
2-1. Docker Compose 설치 (Ubuntu 기준)
sudo apt-get update
sudo apt-get install docker-compose-plugin
요즘엔 예전의
docker-compose바이너리가 아니라docker compose(Docker CLI 플러그인 방식) 를 쓰는 것이 기본입니다.
2-2. 자주 쓰는 Docker Compose 명령어 정리
| 명령어 | 설명 |
|---|---|
docker compose up | docker-compose.yml에 정의된 모든 서비스 실행 |
docker compose up -d | 백그라운드(detached) 모드로 실행 |
docker compose down | 실행 중인 서비스 중지 + 컨테이너 삭제 |
docker compose ps | 현재 Compose로 관리되는 컨테이너 목록/상태 |
docker compose logs [서비스명] | 특정 서비스 로그 확인 |
docker compose exec [서비스명] [명령어] | 컨테이너 내부에서 명령 실행 (예: bash) |
docker compose build | Dockerfile 기반 이미지 빌드 |
3. docker-compose.yml 구조 이해하기
docker-compose.yml 파일은 보통 아래와 같은 요소들로 구성됩니다.
주요 키워드 정리
| 키 | 설명 |
|---|---|
services | 실행할 컨테이너(서비스) 목록 |
image | 사용할 Docker 이미지 |
build | Dockerfile을 이용해 이미지 빌드할 때 사용 |
ports | 호스트:컨테이너 포트 매핑 |
volumes | 데이터/코드 디렉터리 마운트 |
environment | 환경 변수 설정 |
depends_on | 서비스 의존성 정의 (실행 순서) |
networks | 서비스들이 연결될 네트워크 설정 |
volumes (root) | 이름 있는 볼륨 정의 |
networks (root) | 네트워크 정의 |
4. 멀티 컨테이너 예제: Nginx + PostgreSQL
가장 많이 쓰는 패턴 중 하나인
웹 서버(Nginx) + 데이터베이스(PostgreSQL) 예제를 만들어 보겠습니다.
version: "3.9"
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
networks:
- mynetwork
db:
image: postgres:13
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydb
volumes:
- db_data:/var/lib/postgresql/data
networks:
- mynetwork
networks:
mynetwork:
driver: bridge
volumes:
db_data:
이 구성 설명
- web 서비스
nginx:latest이미지 사용- 호스트
80→ 컨테이너80포트 매핑 ./html디렉터리를 Nginx 웹 루트로 마운트db서비스가 먼저 살아있어야 해서depends_on: dbmynetwork네트워크에 연결
- db 서비스
postgres:13이미지 사용POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DB환경변수로 DB 초기 설정db_data볼륨에 실제 데이터를 저장 (컨테이너 삭제해도 데이터 유지)mynetwork네트워크에 연결
- networks.mynetwork
- 두 서비스가 컨테이너 이름으로 서로 통신 가능
(예:web에서db:5432로 접속)
- 두 서비스가 컨테이너 이름으로 서로 통신 가능
- volumes.db_data
- PostgreSQL 데이터를 영구적으로 저장
5. 고급 설정 1 – 헬스 체크 (Healthcheck)
컨테이너가 “실행 중”이라고 해서 “정상 동작” 중이라는 뜻은 아닙니다.
이때 healthcheck를 사용하면, 서비스 상태를 주기적으로 검사할 수 있습니다.
version: "3.9"
services:
web:
image: nginx:latest
ports:
- "80:80"
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost || exit 1"]
interval: 30s
timeout: 10s
retries: 3
헬스 체크 필드 설명
| 필드 | 의미 |
|---|---|
test | 헬스 체크에 사용할 명령 (0 이면 정상) |
interval | 헬스 체크 간격 (예: 30초) |
timeout | 각 체크의 최대 실행 시간 |
retries | 실패 허용 횟수 (이 횟수 이상 실패하면 unhealthy) |
6. 고급 설정 2 – 리소스 제한 (CPU / 메모리)
개발/테스트 환경이라도 리소스를 무제한으로 쓰게 두면
다른 서비스에 영향을 줄 수 있습니다.
Compose에서는 CPU/메모리 제한을 설정할 수 있습니다.
⚠
deploy.resources는 원래 Swarm에서 사용하는 필드이지만,
일부 환경에서는 참고용/문서화 용도로 함께 적어두기도 합니다.
version: "3.9"
services:
web:
image: nginx:latest
ports:
- "80:80"
deploy:
resources:
limits:
cpus: "0.5"
memory: 512M
cpus: "0.5"→ 전체 CPU의 절반만 사용memory: 512M→ 최대 메모리 512MB 제한
7. 고급 설정 3 – 환경변수 파일(.env) 활용
DB 계정, 비밀번호 같은 값은
docker-compose.yml에 직접 적지 말고 .env로 분리하는 것이 좋습니다.
.env 파일 예시
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_DB=mydb
docker-compose.yml에서 사용
version: "3.9"
services:
db:
image: postgres:13
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Compose는 기본적으로 동일 디렉터리의
.env파일을 자동으로 읽습니다.

8. Docker Compose 실전 활용 시나리오
8-1. 개발 환경 구축
- 백엔드(API 서버), DB, Redis, 메시지 큐 등을 컨테이너로 구성
docker compose up -d로 로컬 개발 환경 즉시 구동- 팀원 모두 같은 환경을 재현 가능
8-2. 테스트/스테이징 환경
- 통합 테스트, E2E 테스트를 위해 완전히 분리된 테스트 환경 구성
- CI 파이프라인에서
docker compose up으로 테스트용 인프라 자동 생성
8-3. 웹 애플리케이션 배포
- Nginx + Node.js/Flask + DB 조합으로 웹 서비스 구성
docker compose -f docker-compose.prod.yml up -d식으로 운영용 별도 파일 사용
8-4. 마이크로서비스 아키텍처
- 각 서비스(회원, 결제, 주문 등)를 별도 컨테이너로 분리
- Compose 네트워크를 통해 서비스 간 통신 구성
8-5. 데이터 분석 파이프라인
- Kafka(수집) + Spark(처리) + Grafana(시각화) 등
- 각 단계를 컨테이너로 나누고 Compose로 한 번에 실행
9. Docker Compose에 대해 알아가야 할 점
| 오해 | 진실 |
|---|---|
| Docker Compose는 개발 전용이다 | → 개발에 가장 많이 쓰이지만, Swarm/K8s와 함께 프로덕션에도 활용 가능 |
| 단일 호스트에서만 쓸 수 있다 | → Swarm 모드에서 Compose 파일을 여러 노드에 배포 가능 |
| Dockerfile이 없으면 Compose를 못 쓴다 | → image: 만 지정해도 Docker Hub 이미지로 충분히 사용 가능 |
유용한 실전 팁
- 이미지 캐시 활용: Dockerfile 레이어 순서를 잘 설계하면 빌드 속도 크게 단축
- 최소 권한 원칙: 컨테이너 내부 유저를 root 대신 일반 계정으로 실행
- 로그 관리: log driver, 외부 로깅 시스템(ELK/Promtail 등)과 연동
- 보안 점검: 정기적으로 이미지 취약점 스캔(grype, trivy 등)
- 환경 변수 정리:
.env+env_file로 민감 정보 분리 관리
Q1. Docker Compose와 Docker Swarm의 차이는?
Compose: 단일(또는 소규모) 환경에서 멀티 컨테이너 앱을 정의·실행
Swarm: 여러 서버(노드)에 걸쳐 컨테이너를 클러스터링하고 오케스트레이션
Q2. docker-compose.yml을 수정하면 어떻게 반영하나요?
docker compose up -d
다시 실행하면 변경 사항이 적용됩니다.
필요하면 --build 옵션을 붙여 이미지도 재빌드합니다.
Q3. 컨테이너끼리는 어떻게 통신하나요?
Compose에서 같은 network에 묶인 컨테이너는
서비스 이름으로 통신할 수 있습니다.
예: db:5432, redis:6379