
Docker 9회차 : Docker Compose 입문 (멀티 컨테이너 표준 운영)
현업에서 컨테이너 운영이 어려워지는 순간은 대개 “컨테이너가 여러 개로 늘어났을 때”입니다. 웹 서버, DB, 캐시, 워커 등 서비스가 쪼개지면 docker run 명령은 길어지고, 옵션은 사람마다 달라지며, 재시작/로그/재배포 절차가 팀마다 제각각이 됩니다. Docker Compose는 이런 문제를 하나의 파일(예: compose.yaml)로 정리해, 실행 명령을 표준화하고 서비스 묶음을 일관되게 관리하도록 돕습니다.
목차
- 핵심 개념: Compose가 해결하는 문제
- 핵심 키워드: services, ports, volumes, environment, depends_on
- 산출물: compose.yaml (Web + DB) 예제
- 운영 기본 흐름: 실행/재시작/로그/특정 서비스 재배포
- 초기화(Reset) 가이드: 데이터까지 지우는 방법
- 추가로 생각해볼 점: 실무에서 자주 막히는 포인트
- 블로그 최적화 정보
핵심 개념: Compose가 해결하는 문제
- 실행 명령 표준화: 긴
docker run옵션을 파일로 고정하여, 누가 실행해도 같은 결과가 나오게 만듭니다. - 서비스 묶음 관리: 웹/DB처럼 함께 떠야 하는 컨테이너를 “하나의 애플리케이션 스택”으로 다룹니다.
- 운영 루틴 단순화:
up,down,logs,restart같은 명령이 서비스 묶음 단위로 동작합니다. - 재현 가능한 환경: 로컬/CI/테스트 서버에서 동일한
compose.yaml로 같은 구성의 환경을 재현합니다.
핵심 키워드: services, ports, volumes, environment, depends_on
Compose 파일을 처음 보면 항목이 많아 보이지만, 초보자가 먼저 익힐 것은 아래 5가지입니다. 이 5가지만 이해해도 “웹+DB” 수준의 멀티 컨테이너를 표준 운영 형태로 묶을 수 있습니다.
| 키 | 의미 | 초보자가 자주 실수하는 포인트 |
|---|---|---|
services |
컨테이너(프로세스) 묶음의 정의(웹, DB 등) | 서비스 이름을 애매하게 짓거나(예: app1) 역할이 섞여 유지보수가 어려워집니다. |
ports |
호스트 포트 ↔ 컨테이너 포트 매핑 | 이미 사용 중인 포트(예: 8080)를 또 쓰면 충돌합니다. |
volumes |
데이터/설정 파일을 영속화하거나 공유 | DB 데이터를 볼륨 없이 올리면 컨테이너 삭제 시 데이터가 날아갈 수 있습니다. |
environment |
환경변수로 설정(계정, DB명 등)을 주입 | 민감정보를 파일에 하드코딩하면 공유/커밋 시 유출 위험이 있습니다. |
depends_on |
서비스 시작 순서를 어느 정도 보조 | depends_on만으로 “DB가 완전히 준비됨”을 보장하지는 않습니다(운영 팁에서 보완 방법 설명). |
산출물: compose.yaml 1개 (Web + DB) 예제
아래는 Web + DB를 한 번에 올리는 최소 실습 구성입니다. Web은 DB에 접속할 수 있는 간단한 웹 UI(adminer), DB는 postgres를 사용합니다. 별도 소스 코드 없이도 “멀티 컨테이너 운영 흐름”을 충분히 연습할 수 있습니다.
# compose.yaml
services:
db:
image: postgres:16-alpine
container_name: demo-db
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: app1234
POSTGRES_DB: appdb
TZ: Asia/Seoul
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
restart: unless-stopped
web:
image: adminer:4
container_name: demo-web
ports:
- "8080:8080"
environment:
TZ: Asia/Seoul
depends_on:
- db
restart: unless-stopped
volumes:
db_data:
구성 해설(핵심만)
db서비스는 PostgreSQL을 띄우고,volumes로 데이터 디렉터리를 영속화합니다.web서비스는 Adminer 웹 UI를 8080 포트로 공개합니다. 브라우저에서 DB 접속을 시험할 수 있습니다.depends_on은 “web이 db보다 먼저 뜨지 않도록” 시작 순서를 보조합니다. 다만 DB 준비(초기화)가 늦으면 접속 실패가 날 수 있으니, 운영 섹션에서 보완 팁을 같이 다룹니다.
Adminer 접속 정보(실습용)
- 브라우저:
http://localhost:8080 - 시스템:
PostgreSQL - 서버(Host):
db(Compose 네트워크 내부에서는 서비스명이 곧 호스트명입니다) - 사용자/비밀번호/DB:
app/app1234/appdb
운영 기본 흐름: 실행/재시작/로그/특정 서비스만 재배포
Compose의 진짜 장점은 “올리는 것”이 아니라, 운영 루틴이 팀 표준으로 고정된다는 점입니다. 아래는 초보자가 반드시 손에 익혀야 할 운영 명령들입니다. (참고: 최신 Docker에서는 docker compose가 기본이며, 구버전은 docker-compose 명령을 사용합니다.)
# 1) 실행(백그라운드)
docker compose up -d
# 2) 상태 확인
docker compose ps
# 3) 로그 확인(전체 / 특정 서비스)
docker compose logs --tail=200
docker compose logs -f web
docker compose logs -f db
# 4) 재시작(전체 / 특정 서비스)
docker compose restart
docker compose restart web
# 5) 특정 서비스만 재배포(예: web만 다시 올리기)
docker compose up -d --force-recreate web
# 6) 컨테이너 내부로 들어가기(문제 분석용)
docker compose exec db sh
docker compose exec web sh
# 7) 종료(컨테이너만 내림: 볼륨 데이터는 유지)
docker compose down
| 운영 목표 | 자주 쓰는 명령 | 실무 팁 |
|---|---|---|
| 전체 기동 | docker compose up -d |
한 번에 스택이 올라가므로, 문서/온보딩이 단순해집니다. |
| 로그 추적 | docker compose logs -f web |
장애 시에는 “전체 로그→의심 서비스 로그” 순서로 좁히는 습관이 중요합니다. |
| 서비스만 재기동 | docker compose restart web |
전체 재기동보다 영향 범위가 작아 운영 부담이 줄어듭니다. |
| 특정 서비스만 재배포 | docker compose up -d --force-recreate web |
구성이 바뀌었거나, 컨테이너를 깨끗하게 다시 만들고 싶을 때 사용합니다. |
| 종료(데이터 유지) | docker compose down |
DB 볼륨이 유지되므로, 다음 기동 시 데이터가 남아 있습니다. |
“왜 web에서 DB 호스트를 localhost로 쓰면 안 되나요?”
Compose로 띄운 컨테이너들은 기본적으로 같은 네트워크에 연결되고, 서비스 이름이 DNS 이름처럼 동작합니다. 즉, web 컨테이너 안에서 DB로 접속할 때는 localhost가 아니라 db를 써야 합니다. localhost는 “내 컨테이너 자기 자신”을 가리키기 때문입니다.
depends_on의 한계와 초보자용 안전장치
depends_on은 시작 순서를 보조하지만, DB가 “완전히 준비되어 접속 가능”한 상태까지 기다리지는 않을 수 있습니다. 실무에서는 아래 중 하나를 선택합니다.
- 애플리케이션 레벨 재시도: DB 연결이 실패하면 몇 초 간격으로 재시도하도록 애플리케이션 설정을 둡니다(가장 권장되는 일반 해법).
- healthcheck 도입: DB 서비스에 헬스체크를 붙이고, 준비 상태를 기준으로 의존 서비스를 조절합니다(구성과 이해도가 조금 더 필요).
초기화(Reset) 운영 가이드: “실행/종료/초기화”를 표준 문서로 남기기
Compose 운영에서 가장 자주 필요한 문서는 “어떻게 올리고, 어떻게 내리고, 언제 데이터를 지우는가”입니다. 아래는 팀에서 그대로 복사해 운영 가이드로 써도 되는 형태로 정리한 체크리스트입니다.
1) 실행(기동) 가이드
- 프로젝트 루트에서
compose.yaml파일이 있는지 확인합니다. docker compose up -d로 전체 서비스를 기동합니다.docker compose ps로 web/db가Up상태인지 확인합니다.- 브라우저에서
http://localhost:8080접속 후, 서버에db를 입력해 DB 연결을 확인합니다.
2) 종료(중지/내림) 가이드
- 단순 중지:
docker compose stop
컨테이너는 남아 있고, 다시start로 올릴 수 있습니다. - 스택 내림:
docker compose down
컨테이너/네트워크는 정리되지만,volumes는 기본적으로 유지됩니다(데이터 보존).
3) 초기화(Reset) 가이드
초기화는 2단계로 나누는 것이 안전합니다. “컨테이너만 정리”와 “데이터까지 삭제”는 영향도가 완전히 다릅니다.
| 초기화 수준 | 명령 | 무엇이 지워지나요? |
|---|---|---|
| 컨테이너만 초기화 | docker compose down |
컨테이너/네트워크 정리, DB 데이터(볼륨)는 유지 |
| 데이터까지 완전 초기화 | docker compose down -v |
컨테이너/네트워크 + 볼륨까지 삭제(DB 데이터 사라짐) |
# (권장) 데이터 유지 초기화
docker compose down
# (주의) 데이터까지 완전 초기화 - DB 볼륨 삭제
docker compose down -v
# 이미지 최신화 후 재기동(필요 시)
docker compose pull
docker compose up -d
추가로 생각해볼 점: 실무에서 자주 막히는 포인트
- 환경변수 관리: 실무에서는 비밀번호를 파일에 직접 쓰기보다
.env또는 CI 비밀변수로 주입하는 방식이 안전합니다. - 포트 충돌: 로컬에 이미 Postgres가 있으면
5432가 충돌합니다.
이 경우 호스트 포트를 바꿔"15432:5432"처럼 운영하는 방식이 흔합니다. - 볼륨 백업: DB 운영은 “삭제 전 백업”이 기본입니다. 초기화 전에 데이터 백업/덤프 루틴을 팀 규칙으로 정해두면 사고를 줄일 수 있습니다.
- 로그 습관: 장애 대응은
docker compose logs -f부터 시작하는 것이 가장 빠릅니다. 문제가 web인지 db인지부터 분리해 보시는 것이 좋습니다. - 서비스 분리 기준: “함께 배포/스케일링/장애영향이 같은가?”를 기준으로 서비스를 나누면 Compose/운영 설계가 자연스럽습니다.
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
'Docker' 카테고리의 다른 글
| Docker 10회차 : 운영 관점 기초 (보안/환경변수/헬스체크/리소스/정리) (0) | 2026.01.01 |
|---|---|
| Docker 8회차 : 컨테이너 네트워크 (포트, 브리지 네트워크, DNS) (0) | 2026.01.01 |
| Docker 7회차 : 데이터 보존 (Volumes & Bind Mount) (0) | 2026.01.01 |
| Docker 6회차 : Dockerfile 기초 (나만의 이미지 만들기) (0) | 2026.01.01 |
| Docker 5회차 : 이미지 사용 전략 (pull, tag, inspect, history) (0) | 2026.01.01 |