Docker Compose health-gated reverse proxy stack
무엇을 학습
FastAPI/Next.js/Postgres/Redis 서비스를 Docker Compose와 NPM/Nginx reverse proxy 뒤에서 운영할 때, “컨테이너 running”이 아니라 “서비스 ready”를 기준으로 startup, deploy, smoke test를 설계한다. 1. `depends_on` short syntax는 준비 완료를 보장하지 않는다. 2. dependency…
어디에 정리
02_Code_Senior/Patterns/docker-compose-health-gated-reverse-proxy-stack.md
앞으로 어떻게 쓸 것인가
브리프·체크리스트·자동화 패턴에 즉시 참조
Docker Compose health-gated reverse proxy stack
목적
FastAPI/Next.js/Postgres/Redis 서비스를 Docker Compose와 NPM/Nginx reverse proxy 뒤에서 운영할 때, “컨테이너 running”이 아니라 “서비스 ready”를 기준으로 startup, deploy, smoke test를 설계한다.
핵심 규칙
depends_onshort syntax는 준비 완료를 보장하지 않는다.- dependency service에
healthcheck를 둔다. - dependent service는 long syntax
condition: service_healthy를 사용한다. depends_on.restart: true는 명시적 Compose 재시작/업데이트 후 dependent 재시작을 유도하는 장치이지, 모든 runtime crash 전파를 뜻하지 않는다.- proxy health와 internal health를 분리해서 테스트한다.
Compose 템플릿
services:
api:
build: ./api
depends_on:
db:
condition: service_healthy
restart: true
redis:
condition: service_started
healthcheck:
test: ["CMD-SHELL", "python -c 'import urllib.request; urllib.request.urlopen(\"http://127.0.0.1:8000/healthz\", timeout=2)'"]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s
db:
image: postgres:18
environment:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 10s
retries: 5
start_period: 30s
redis:
image: redis:7
FastAPI health endpoint 기준
from fastapi import FastAPI
app = FastAPI()
@app.get('/healthz')
def healthz():
return {'status': 'ok'}
운영형 readiness는 별도 /readyz에서 DB ping/config check를 수행한다. /healthz는 너무 무겁게 만들지 않는다.
systemd wrapper 예시
[Unit]
Description=project compose stack
After=docker.service network-online.target
Requires=docker.service
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/my-project
ExecStart=/usr/bin/docker compose up -d --remove-orphans
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=180
Restart=on-failure
RestartSec=10s
RestartSteps=4
RestartMaxDelaySec=160s
[Install]
WantedBy=multi-user.target
RestartSteps/RestartMaxDelaySec는 systemd 254+ 기능이다. 적용 전 대상 서버의 systemctl --version을 확인한다.
배포 후 검증 순서
# 1. Compose 상태
/usr/bin/docker compose ps
# 2. Internal health
/usr/bin/docker compose exec api python -c 'import urllib.request; print(urllib.request.urlopen("http://127.0.0.1:8000/healthz", timeout=3).status)'
# 3. Proxy health
curl -fsS https://app.example.com/healthz
장애 분류
- internal health 실패: app boot, dependency readiness, migration, env/config 문제 우선.
- internal health 성공 + proxy 실패: NPM host, upstream host/port, Docker network, DNS, TLS, firewall 문제 우선.
- dependency가 자주 재시작: Compose/Docker restart policy, DB volume, credential/env, resource limit 확인.
관련 링크
- [[2026-06-07]]
- Docker Compose startup order: https://docs.docker.com/compose/how-tos/startup-order/
- Docker Compose
depends_on: https://docs.docker.com/reference/compose-file/services/#depends_on - Docker Compose
healthcheck: https://docs.docker.com/reference/compose-file/services/#healthcheck - systemd.service: https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html
Study Room
내일 학습·스터디 큐
내일 학습 큐가 아직 추출되지 않았습니다.
스터디 대화
코칭뿐 아니라 학습 내용에 대해 에이전트별 토론·스터디 지시를 남기는 공간입니다. 저장된 메시지는 다음 학습 큐 조정의 근거가 됩니다.
아직 스터디 대화가 없습니다.