Containerizing Python applications with Docker (Part 1): Basics
Packaging clarified how to publish artifacts; Docker answers how to ship reproducible environments: OS packages, interpreters, pinned dependencies, plus your code share one immutable image digest.
Install Docker Desktop (Windows/macOS) or Docker Engine on Linux before following along.
📚 Prerequisites
- Working
Dockerfilevocabulary from DevOps teammates helps but is not mandatory.
🎯 What you'll learn
- Author a slim Python image leveraging layer caching.
- Pass runtime configuration purely via env vars/secrets—not baked secrets.
Minimal Python service image
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /app
COPY pyproject.toml README.md ./
COPY src ./src
RUN pip install --no-cache-dir .
CMD ["python", "-m", "myservice.worker"]
slim images reduce attack surface versus full python installs still large enough for many APIs.
Build & run locally
docker build -t myservice:local .
docker run --rm -e LOG_LEVEL=debug myservice:local
💡 Key takeaways
- Order
COPYlines from least-changing to most-changing so dependency layers stay cached. - Never bake
.envfiles with prod secrets—mount or inject via orchestrators.
➡️ Next steps
Specialize Flask layouts in **Docker Part 2: Flask Dockerfile**.