C.W.K.
Stream
Lesson 06 of 06 · published

Production-Ready Dockerfile — non-root, healthcheck, label

~16 min · dockerfile, production, security

Level 0Container 호기심
0 XP0/36 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

Production Dockerfile 이 옳게 하는 5가지

  1. Multi-stage — 작은 최종 image.
  2. Non-root user — CMD 전에 권한 떨궈.
  3. HEALTHCHECK — Docker (와 오케스트레이터) 가 앱이 진짜 준비됐는지 알 수 있게.
  4. Exec-form CMD — JSON 배열, shell 문자열 X. PID 1 이 시그널 제대로 받게.
  5. LABEL — 버전, 소스, 메인테이너. registry 에서 검색 가능.

시그널과 graceful shutdown

CMD python app.py (shell form) 쓰면 Docker 는 실제로 /bin/sh -c "python app.py" 돌려. PID 1 이 shell 이지 Python 아니야. SIGTERM 이 shell 한테 가는데, shell 은 forward 안 해. Python 앱은 10초 grace 후 SIGKILL — cleanup 기회 없어.

항상 CMD ["python", "app.py"] (exec form) 써. PID 1 이 Python 직접. SIGTERM 이 핸들러 도달. Graceful shutdown 동작.

Code

Production FastAPI Dockerfile·dockerfile
# Stage 1: install deps
FROM python:3.12-slim AS deps
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Stage 2: runtime
FROM python:3.12-slim AS runtime
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1

# Labels
LABEL org.opencontainers.image.source="https://github.com/cwk/myapi"
LABEL org.opencontainers.image.version="1.0.0"
LABEL org.opencontainers.image.licenses="MIT"

# Pull installed packages from deps stage
COPY --from=deps /usr/local/lib/python3.12/site-packages \
                 /usr/local/lib/python3.12/site-packages
COPY --from=deps /usr/local/bin /usr/local/bin

# App code
COPY . .

# Non-root user (create AND switch)
RUN addgroup --system app && adduser --system --group app
USER app

EXPOSE 8000

# Healthcheck — let Docker/k8s know when app is up
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
  CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1

# Exec form so SIGTERM reaches Python directly
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

External links

Exercise

이 트랙의 최소 Dockerfile 가져와서 강화: multi-stage 변환, non-root user, HEALTHCHECK, CMD 를 exec form 으로, OCI label 3개. Build, run, docker ps(healthy) 보이는지 확인 + container 안 process 가 root 아닌 거 확인 (docker exec ... whoami).

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.