Docker & Containerization

Writing Dockerfiles

35 Min.

A Dockerfile for a Flask app

FROM python:3.12-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    PIP_NO_CACHE_DIR=1

WORKDIR /app

# 1. dependencies first (cached unless requirements change)
COPY requirements.txt .
RUN pip install -r requirements.txt

# 2. then the source code (changes often)
COPY . .

ENV PORT=8000
EXPOSE 8000
CMD ["gunicorn", "wsgi:app", "-c", "gunicorn.conf.py"]
docker build -t myapp:dev .
docker run --rm -p 8000:8000 --env-file .env myapp:dev

Layers and the build cache

Each instruction creates a layer. Docker reuses cached layers until something changes, then rebuilds everything after it. Copying requirements.txt and installing before copying the code means a code change does not reinstall every package, turning a 3-minute build into 5 seconds.

.dockerignore

Keep junk and secrets out of the build context:

.git
.venv
__pycache__/
*.pyc
.env
*.db
node_modules/
uploads/
tests/

Without it, COPY . . can bake your .env file into the image, where anyone with the image can read it.

Instructions you will use

Instruction Purpose
FROM base image
WORKDIR working directory
COPY copy files into the image
RUN run a command at build time
ENV environment variable
EXPOSE document the listening port
USER run as a non-root user
CMD default command when the container starts
HEALTHCHECK how to tell if the app is healthy

Use the exec form CMD ["gunicorn", ...] (a JSON array) so signals reach your app and it shuts down gracefully.

Choosing a base image

  • python:3.12-slim: small Debian-based image; the best default.
  • python:3.12-alpine: smaller, but uses musl libc, so many Python packages must compile from source. Often slower to build and occasionally incompatible.
  • Pin the version (3.12-slim, not latest) so builds are reproducible.

Exercise

Containerise a small Flask app with a .dockerignore, build it, run it with an env file, change a template and confirm the rebuild reuses the dependency layer.

Check yourself

  • Why copy requirements.txt before the rest of the code?
  • What can happen without a .dockerignore?
  • Why prefer the exec form of CMD?

Ihr Fortschritt wird nur in diesem Browser gespeichert.

Zur Prüfung einreichen (10 Punkte)