빠른 흐름
services:
web:
build: .
depends_on:
db:
condition: service_healthy
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5설정 흐름
어떤 Compose 시작 제어 기준을 먼저 떠올리면 되나
| 상황 | 먼저 떠올릴 선택 |
|---|---|
| 단순 시작 순서만 맞추기 | depends_on |
| 실제 준비 완료 뒤 시작 | condition: service_healthy |
| 이미지에 헬스체크가 없다 | Compose healthcheck 직접 정의 |
| 초기화가 오래 걸린다 | start_period 조정 |
depends_on만으로는 준비 상태를 보장하지 못한다 — 컨테이너 시작과 서비스 준비는 다르다
depends_on의 기본 동작은 의존 컨테이너가 "생성되어 실행 상태가 됐는지"만 확인합니다. DB 컨테이너가 Running 상태가 됐다고 해서 PostgreSQL이 실제로 쿼리를 받을 준비를 마친 것은 아닙니다. DB 초기화가 끝나기 전에 앱 컨테이너가 먼저 연결을 시도하면 연결 실패로 앱이 죽습니다.
# 위험한 패턴 — DB가 '실행 중'이어도 준비 안 됐을 수 있음
services:
web:
depends_on:
- db # condition 없이 쓰면 service_started가 기본condition: service_healthy — healthcheck 통과 후 다음 서비스를 시작한다
depends_on에 condition: service_healthy를 지정하면, 의존 서비스의 healthcheck가 지정된 횟수 이상 성공할 때까지 다음 서비스 시작을 기다립니다. DB가 실제로 연결 가능한 상태임을 확인한 뒤 앱을 올리므로, 시작 순서로 인한 연결 실패를 방지합니다.
services:
web:
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 10
start_period: 10s # 초기 기동 시간 여유
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
retries: 5Dockerfile HEALTHCHECK와 Compose healthcheck — 같은 개념이지만 위치가 다르다
Dockerfile에도 HEALTHCHECK 지시어가 있어 이미지 자체에 헬스체크를 내장할 수 있습니다. Compose의 healthcheck 블록은 이미지에 정의된 헬스체크를 덮어쓰거나, 없는 경우에 추가합니다. 팀 공용 이미지에 헬스체크를 넣으면 Compose에서 별도 정의 없이도 service_healthy 조건을 쓸 수 있습니다.
# Dockerfile에 헬스체크 내장
HEALTHCHECK --interval=10s --timeout=3s --retries=5 \
CMD pg_isready -U postgres || exit 1체크포인트
| 상황 | 적합한 선택 |
|---|---|
| 단순 시작 순서만 제어할 때 | depends_on + condition: service_started |
| DB/캐시가 완전히 준비된 뒤 앱을 올릴 때 | depends_on + condition: service_healthy |
| 헬스체크가 없는 이미지 사용 시 | Compose healthcheck 블록에서 직접 정의 |
| 헬스체크를 팀 공용 이미지에 내장하고 싶을 때 | Dockerfile HEALTHCHECK 지시어 |
| 초기 기동 시간이 긴 서비스 | start_period 설정으로 초기 판정 유예 |
주의할 점
depends_on만 넣고 안심하면 안 된다. DB, 캐시, 메시지 큐처럼 초기화 시간이 있는 서비스는 반드시 healthcheck와 condition: service_healthy를 함께 설정해야 한다. 로컬에서는 타이밍이 맞아 동작해도 CI나 느린 환경에서는 연결 실패가 발생한다.
참고 링크
2 sources