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.

4 min de leitura Equipe Python Brasil

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 slim ou alpine para reducao de tamanho
  • Copie requirements.txt antes do codigo para aproveitar cache de camadas
  • Nunca execute containers como root em producao
  • Use .dockerignore para evitar copiar arquivos desnecessarios
  • Defina HEALTHCHECK para 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.

E

Equipe Python Brasil

Contribuidor do Python Brasil — Aprenda Python em Português