WarpBuild LogoWarpBuild Docs

Python with uv

Best practices for Dockerfile for Python with uv

🐳 Annotated Dockerfile for Python with uv:

# Use a slim and modern base image: Python 3.12 on Debian Bookworm
FROM python:3.12-slim-bookworm AS base
 
# --------------------------------------
# Stage 1: Builder - installs dependencies and prepares environment
# --------------------------------------
FROM base AS builder
 
# Copy pre-built uv binary from official image
COPY --from=ghcr.io/astral-sh/uv:0.6 /uv /bin/uv
 
# Enable uv optimizations:
# UV_COMPILE_BYTECODE=1 compiles Python bytecode for faster startup
# UV_LINK_MODE=copy ensures dependencies are copied (isolated env)
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
 
# Set the working directory in container to /app
WORKDIR /app
 
# Copy dependency files
COPY pyproject.toml uv.lock /app/
 
# Create a virtual environment first
RUN uv venv
 
# Install dependencies from the lock file
RUN --mount=type=cache,target=/root/.cache/uv \
  uv pip install -r uv.lock --no-deps
 
# Now copy the source code
COPY . /app
 
# Install your project itself
RUN --mount=type=cache,target=/root/.cache/uv \
  uv pip install -e .
 
# --------------------------------------
# Stage 2: Final production image - minimal and optimized
# --------------------------------------
FROM base
 
# Copy prepared app environment from builder stage
COPY --from=builder /app /app
 
# Add virtual environment bin folder to PATH for easy command access
ENV PATH="/app/.venv/bin:$PATH"
 
# Expose port 8000 for application server
EXPOSE 8000
 
# Default command to start your Python app
CMD ["python", "app.py"]

🔍 Why these are best practices

✅ Slim Base Images (python:3.12-slim-bookworm)

  • Minimizes image size, enhancing security and reducing container startup time.
  • Debian Bookworm provides modern dependencies with stable long-term support.

✅ Using uv (Ultra-fast Python package manager)

  • Faster and more efficient than traditional pip.
  • Built-in dependency caching significantly improves build speeds.
  • Ensures reproducible builds through lock files (uv.lock), avoiding dependency drift.

✅ Multi-stage Builds

  • Keeps final image minimal by excluding build-time artifacts (e.g., cache files, temporary dependencies).
  • Reduces production container size, resulting in lower resource usage and faster deployments.

✅ Dependency and Source Separation

  • Copying dependency-related files separately allows Docker to reuse cached layers effectively.
  • Changes in source code don’t trigger unnecessary reinstallations of unchanged dependencies.

✅ Mounting Cache (--mount=type=cache)

  • Dramatically reduces build time in CI/CD environments by reusing cached downloads and installed packages.

✅ Environment Variables

  • UV_COMPILE_BYTECODE=1 compiles bytecode, which optimizes startup times in production.
  • UV_LINK_MODE=copy isolates dependencies clearly, simplifying management and ensuring immutability.

🚀 Additional best practices to consider

Run as a Non-root User

For enhanced security, switch to a non-root user in your production container.

FROM base
 
RUN useradd -m appuser
COPY --from=builder /app /app
ENV PATH="/app/.venv/bin:$PATH"
WORKDIR /app
 
USER appuser
 
EXPOSE 8000
CMD ["uvicorn", "uv_docker_example:app", "--host", "0.0.0.0", "--port", "8000"]

Add Health Checks

Integrate Docker’s built-in health monitoring to enable auto-recovery mechanisms.

HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8000/health || exit 1
 
(This requires adding a /health endpoint to your Python app.)

Use .dockerignore file

Avoid accidentally copying unwanted files (e.g., logs, .git, test folders):

.venv
__pycache__
*.pyc
.git
tests/
docker-compose.yml

Explicit Resource Limits

Set CPU and memory limits explicitly when running containers (via Kubernetes, Docker Compose, or runtime flags).

Example (Docker Compose):

services:
  web:
    build: .
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: "512M"

By following these annotations and additional best practices, you’ll achieve containers that are fast to build, secure, easy to maintain, and optimized for production environments.

Last updated on

On this page