Containerizar uma API Python parece simples — até você precisar de logs estruturados, healthcheck, graceful shutdown e multi-stage build para uma imagem final < 100MB. Esta aula reproduz o template que usamos no lab.
O Dockerfile final (que vamos construir)
1 | # ===== Stage 1: build ===== |
Resultado: imagem final de ~92MB.
Passo 1 — Multi-stage cuts your image in half
O truque do multi-stage é instalar dependências em um stage descartável (builder), e copiar apenas o resultado para o stage final. Sem isso, sua imagem carrega gcc, headers do Python, cache do pip — tudo desnecessário em runtime.
| Approach | Tamanho final |
|---|---|
python:3.12 + pip install |
980 MB |
python:3.12-slim + pip install |
280 MB |
python:3.12-slim + multi-stage |
92 MB |
python:3.12-alpine + multi-stage |
68 MB ⚠️ |
Alpine é menor, mas dá problemas com libs que dependem de glibc (numpy, scipy, pandas). Para APIs simples, vale. Para data-science, fique no slim.
Passo 2 — Por que gunicorn + uvicorn workers?
FastAPI é ASGI (async). Uvicorn é o servidor ASGI de referência. Mas em produção:
- Uvicorn sozinho: processo único. Se ele crashar, sua API morre.
- Gunicorn como process manager: fork de N workers, restart automático, graceful shutdown.
- Workers do tipo
UvicornWorker: gunicorn gerencia, uvicorn executa o async.
A combinação dá robustez de process manager + performance async. É o padrão recomendado pela própria documentação do FastAPI.
Passo 3 — Healthcheck que faz sentido
1 |
|
Esse /health é usado tanto pelo HEALTHCHECK do Dockerfile quanto pelo liveness/readiness do Kubernetes. Não retorne sempre 200: o healthcheck precisa falhar se o banco cair, senão o orchestrator nunca remove o pod doente do load balancer.
Passo 4 — Logs estruturados
1 | import logging, json |
Logs JSON são indispensáveis para qualquer ferramenta de observability (CloudWatch, Datadog, Grafana Loki) extrair campos.
Passo 5 — Graceful shutdown
1 | from contextlib import asynccontextmanager |
Sem isso, ao escalar para baixo, conexões DB ficam abertas no servidor, requests em vôo são abortadas.
Resultado
Imagem final pronta para:
- ECS Fargate
- Cloud Run
- Kubernetes
- Docker Compose em produção (com Caddy/Nginx na frente)
E roda em qualquer plataforma sem mudança.