Docker & Containerization

Production-Ready Images

35 min

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 ENV values are visible in the image history.
  • Minimal images: fewer packages, fewer vulnerabilities.
  • Scan images: docker scout cves myapp:latest or 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-only with a writable /tmp volume).

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 SIGTERM gracefully (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 ENV or build args unsafe?
  • Where should a containerised app write logs?

Votre progression est enregistrée dans ce navigateur uniquement.

Envoyer pour relecture (10 points)