Python e Docker: Guia Completo — 2025 | Python Brasil
Aprenda a containerizar aplicacoes Python com Docker. Dockerfile otimizado, docker-compose, multi-stage builds e boas praticas de producao.
Docker revolucionou a forma como empacotamos e distribuimos aplicacoes. Com containers, voce garante que o ambiente de desenvolvimento e identico ao de producao, eliminando o classico “na minha maquina funciona”. Neste guia, a gente vai aprender a containerizar aplicacoes Python do zero, com exemplos otimizados para producao.
Por Que Usar Docker com Python?
Projetos Python frequentemente dependem de versoes especificas do interpretador, bibliotecas nativas e configuracoes de ambiente. Docker resolve todos esses problemas encapsulando a aplicacao e suas dependencias em um container isolado e reproduzivel.
Dockerfile Basico para Python
Vamos comecar com uma aplicacao Flask simples. Primeiro, a estrutura do projeto:
meu-projeto/
app.py
requirements.txt
Dockerfile
.dockerignore
O arquivo app.py:
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def index():
return jsonify({"mensagem": "Ola do container Docker!", "status": "ok"})
@app.route("/saude")
def saude():
return jsonify({"status": "saudavel"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
O requirements.txt:
flask==3.0.0
gunicorn==21.2.0
Agora o Dockerfile:
# Imagem base
FROM python:3.12-slim
# Definir diretorio de trabalho
WORKDIR /app
# Copiar e instalar dependencias primeiro (cache de camadas)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copiar codigo da aplicacao
COPY . .
# Expor a porta
EXPOSE 5000
# Comando para executar
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "4", "app:app"]
O .dockerignore:
__pycache__
*.pyc
.git
.env
venv/
.venv/
*.md
.pytest_cache/
Construindo e Executando
# Construir a imagem
docker build -t minha-app-python .
# Executar o container
docker run -d -p 5000:5000 --name minha-app minha-app-python
# Verificar logs
docker logs minha-app
# Testar
curl http://localhost:5000/
# {"mensagem": "Ola do container Docker!", "status": "ok"}
Multi-Stage Build para Imagens Menores
Multi-stage builds permitem separar a fase de build da imagem final, reduzindo drasticamente o tamanho:
# Estagio 1: Build
FROM python:3.12-slim AS builder
WORKDIR /app
# Instalar dependencias de build
RUN apt-get update && apt-get install -y --no-install-recommends gcc
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
# Estagio 2: Producao
FROM python:3.12-slim
WORKDIR /app
# Copiar apenas as dependencias instaladas
COPY --from=builder /install /usr/local
# Criar usuario nao-root
RUN useradd --create-home appuser
USER appuser
COPY --chown=appuser:appuser . .
EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "4", "app:app"]
Essa abordagem pode reduzir a imagem de mais de 400 MB para menos de 150 MB.
Docker Compose para Ambientes Completos
Na pratica, aplicacoes precisam de banco de dados, cache e outros servicos. O Docker Compose orquestra tudo:
# docker-compose.yml
version: "3.9"
services:
web:
build: .
ports:
- "5000:5000"
environment:
- DATABASE_URL=postgresql://user:senha@db:5432/minha_app
- REDIS_URL=redis://cache:6379/0
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
volumes:
- .:/app # Para desenvolvimento
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: senha
POSTGRES_DB: minha_app
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 5s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Para usar:
# Subir todos os servicos
docker compose up -d
# Ver logs de todos os servicos
docker compose logs -f
# Parar tudo
docker compose down
# Reconstruir apos mudancas no Dockerfile
docker compose up -d --build
Configuracao para Desenvolvimento vs Producao
Separe as configuracoes usando arquivos compose diferentes:
# docker-compose.override.yml (desenvolvimento - aplicado automaticamente)
version: "3.9"
services:
web:
command: python app.py # Modo debug ao inves de gunicorn
volumes:
- .:/app
environment:
- FLASK_ENV=development
- FLASK_DEBUG=1
# docker-compose.prod.yml
version: "3.9"
services:
web:
volumes: [] # Sem volume mount em producao
environment:
- FLASK_ENV=production
deploy:
replicas: 3
resources:
limits:
cpus: "0.5"
memory: 512M
Para producao:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Variaveis de Ambiente e Segredos
Nunca coloque senhas diretamente no Dockerfile. Use variaveis de ambiente:
import os
class Config:
"""Configuracao carregada de variaveis de ambiente."""
DATABASE_URL = os.environ.get("DATABASE_URL", "sqlite:///local.db")
REDIS_URL = os.environ.get("REDIS_URL", "redis://localhost:6379/0")
SECRET_KEY = os.environ.get("SECRET_KEY", "chave-dev-insegura")
DEBUG = os.environ.get("FLASK_DEBUG", "0") == "1"
Use um arquivo .env para desenvolvimento:
# .env (nunca comite este arquivo)
DATABASE_URL=postgresql://user:senha@db:5432/minha_app
SECRET_KEY=minha-chave-super-secreta
FLASK_DEBUG=1
Healthcheck na Aplicacao
Adicione endpoints de saude para monitoramento:
from flask import Flask, jsonify
import psycopg2
import redis
@app.route("/saude")
def healthcheck():
"""Endpoint de healthcheck para Docker e orquestradores."""
status = {"api": "ok"}
try:
r = redis.from_url(app.config["REDIS_URL"])
r.ping()
status["redis"] = "ok"
except Exception:
status["redis"] = "erro"
return jsonify(status), 200 if all(v == "ok" for v in status.values()) else 503
No Dockerfile:
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -f http://localhost:5000/saude || exit 1
Boas Praticas
Ao containerizar aplicacoes Python, siga estas recomendacoes:
- Use imagens
slimoualpinepara reducao de tamanho - Copie
requirements.txtantes do codigo para aproveitar cache de camadas - Nunca execute containers como root em producao
- Use
.dockerignorepara evitar copiar arquivos desnecessarios - Defina
HEALTHCHECKpara monitoramento automatico - Use multi-stage builds para separar build de producao
- Congele versoes das dependencias no
requirements.txt - Nao armazene dados dentro do container, use volumes
Conclusao
Docker e uma ferramenta indispensavel para projetos Python modernos. Com Dockerfiles otimizados, multi-stage builds e Docker Compose, voce garante ambientes reproduziveis e deploys confiaveis. Comece containerizando um projeto simples e gradualmente adote praticas mais avancadas como orquestracao com Kubernetes. O investimento em Docker se paga rapidamente na produtividade do time.
Equipe Python Brasil
Contribuidor do Python Brasil — Aprenda Python em Português