Overview Most developers begin their containerization journey with a bloated Dockerfile that results in massive images and sluggish deployment pipelines. An unoptimized image often exceeds a gigabyte, dragging down CI/CD performance and increasing cloud storage costs. By moving away from heavy generic OS images like Ubuntu and adopting modern tooling, you can reduce image sizes by over 80% while significantly hardening security. Prerequisites To follow this guide, you should have a baseline understanding of Python development and Docker fundamentals. Familiarity with the terminal, basic shell commands, and the concept of virtual environments will help you navigate the more advanced multi-stage build patterns. Key Libraries & Tools - FastAPI: A high-performance web framework for building APIs with Python. - Poetry: A tool for dependency management and packaging in Python. - uv: An extremely fast Python package installer and resolver written in Rust. - Debian: The Linux distribution serving as the foundation for most official Python images. Refined Base Images and Tagging Standard Python images often include unnecessary build tools and headers. Switching to `python:3.13-slim-bookworm` provides a minimal Debian base without the bloat. Furthermore, avoid the `latest` tag; it is a rolling target that introduces unpredictability. Specific tags ensure your production environment remains consistent and reproducible. The Multi-Stage Build Pattern This technique separates the build environment from the runtime environment. You use a heavy image with compilers to install dependencies, then copy only the resulting virtual environment into a slim production image. ```dockerfile Stage 1: Builder FROM python:3.13-bookworm AS builder COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv WORKDIR /app COPY pyproject.toml . RUN uv venv && uv sync Stage 2: Runtime FROM python:3.13-slim-bookworm WORKDIR /app COPY --from=builder /app/.venv /.venv ENV PATH="/.venv/bin:$PATH" COPY ./src ./src CMD ["uvicorn", "src.main:app"] ``` Syntax Notes and Performance Using `apt-get install --no-install-recommends` prevents the installation of suggested packages that aren't strictly required. Additionally, chaining `rm -rf /var/lib/apt/lists/*` in the same `RUN` layer clears out the package index metadata, which serves no purpose in a final production image. Practical Examples In a real-world FastAPI deployment, applying these steps took an image from nearly 1GB down to roughly 150MB. By using uv instead of Poetry inside the Dockerfile, build times dropped from 36 seconds to under 9 seconds due to faster dependency resolution. Tips & Gotchas Always run your container as a non-root user to prevent attackers from gaining system-level access. Use `RUN useradd -m appuser && USER appuser`. A common mistake is copying the entire project directory (`COPY . .`), which can accidentally leak `.env` files or include heavy local artifacts like `node_modules` or `__pycache__`.
Debian
Products
- Mar 14, 2025