Production-Ready Images
Multi-stage builds
Build tools are needed to compile packages but not to run the app. Multi-stage builds keep them out of the final image:
# ---- build stage ----
FROM python:3.12-slim AS build
RUN apt-get update && apt-get install -y --no-install-recommends build-essential \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt .
RUN pip wheel --wheel-dir /wheels -r requirements.txt
# ---- runtime stage ----
FROM python:3.12-slim
ENV PYTHONUNBUFFERED=1
RUN useradd --create-home --uid 10001 appuser
WORKDIR /app
COPY --from=build /wheels /wheels
RUN pip install --no-cache-dir /wheels/* && rm -rf /wheels
COPY --chown=appuser:appuser . .
USER appuser
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD python -c "import urllib.request,sys; urllib.request.urlopen('http://127.0.0.1:8000/api/health', timeout=4)" || exit 1
CMD ["gunicorn", "wsgi:app", "-c", "gunicorn.conf.py"]
Security essentials
- Run as a non-root user (
USER appuser). If the app is compromised, the attacker is not root inside the container. - No secrets in images: pass them at runtime as environment variables or mounted secrets. Build arguments and
ENVvalues are visible in the image history. - Minimal images: fewer packages, fewer vulnerabilities.
- Scan images:
docker scout cves myapp:latestor Trivy (trivy image myapp:latest) in CI. - Pin and update base images regularly to pick up security patches.
- Read-only root filesystem where possible (
--read-onlywith a writable/tmpvolume).
Image size
docker images myapp
docker history myapp:latest # size of each layer
Clean package caches in the same RUN that creates them (rm -rf /var/lib/apt/lists/*); files deleted in a later layer still take space in the earlier one.
Logs and signals
- Write logs to stdout/stderr; the platform collects them.
- Handle
SIGTERMgracefully (Gunicorn does) so in-flight requests finish during deploys.
Exercise
Convert your Dockerfile to a multi-stage build that runs as a non-root user with a health check. Compare image sizes before and after and scan both for vulnerabilities.
Check yourself
- Why use a multi-stage build?
- Why are secrets in
ENVor build args unsafe? - Where should a containerised app write logs?
進捗はこのブラウザーにのみ保存されます。
レビューに提出(10 ポイント)