Aller au contenu principal
Docker best practices for Python applications
DevOps

Docker best practices for Python applications

1 minParcours PlateformeDomaine DevOpsLangue en
  • Docker
  • Python
  • Containers
  • CI/CD
  • Best Practices
Daya SYLLA;
Daya SYLLA
Publié le
Lire en français

Docker best practices for Python applications

Docker is central to development and deployment. Here are solid practices for containerizing Python apps.

Dockerfile structure

1. Multi-stage builds

# Stage 1: Builder
FROM python:3.10-slim as builder
WORKDIR /build
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# Stage 2: Production
FROM python:3.10-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]

Benefits:

  • Smaller final image
  • Better security (no build tools in prod)
  • Faster rebuilds when only app code changes

2. Prefer slim images

Avoid:

FROM python:3.10  # ~900 MB

Prefer:

FROM python:3.10-slim  # ~120 MB

3. Layer cache optimization

# Copy requirements first (changes less often)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code last (changes more often)
COPY . .

Security

1. Non-root user

RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser

2. Do not bake in secrets

Bad:

ENV API_KEY=secret123

Good:

# Use Docker secrets or runtime environment variables
# docker run -e API_KEY=secret123

3. Scan for vulnerabilities

trivy image myapp:latest

Performance

1. .dockerignore

__pycache__
*.pyc
*.pyo
*.pyd
.Python
env/
venv/
.git/
.gitignore
README.md

2. Health checks

HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/health || exit 1

3. Labels for metadata

LABEL maintainer="Daya SYLLA <dev@example.com>"
LABEL version="1.0"
LABEL description="Flask Portfolio Application"

Docker Compose

Example service

version: '3.8'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      - FLASK_ENV=production
    volumes:
      - ./app:/app
    ports:
      - "8080:8080"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3

CI/CD integration

GitHub Actions

name: Build and Push
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .
      - name: Push to registry
        run: docker push myapp:${{ github.sha }}

Monitoring

Structured logs

import logging
import json

logging.basicConfig(
    format='%(asctime)s %(levelname)s %(message)s',
    level=logging.INFO
)

Metrics

  • Expose Prometheus metrics
  • Add a /metrics endpoint
  • Visualize with Grafana

Conclusion

These practices help you build Docker images that are lean, secure, and easy to operate—improving both development and deployment workflows.