Docker para Python: Guia Completo
Aprenda a configurar Docker para projetos Python. Dockerfile, docker-compose, boas práticas, multi-stage builds e deploy de aplicações
Introdução
Docker é uma ferramenta que permite empacotar sua aplicação Python junto com todas as suas dependências em um container isolado. Isso garante que o código funcione da mesma forma no seu computador, no servidor de produção e na máquina de qualquer colega de equipe.
Neste guia, vamos configurar Docker para projetos Python, criar Dockerfiles otimizados e usar docker-compose para aplicações com múltiplos serviços.
Pré-requisitos
Instale o Docker Desktop no seu sistema operacional:
- macOS:
brew install --cask dockerou baixe em docker.com - Windows: baixe o Docker Desktop e habilite o WSL 2
- Linux: instale via gerenciador de pacotes da sua distribuição
Verifique a instalação:
docker --version
docker compose version
Conceitos básicos
- Imagem: template somente leitura que define o ambiente (sistema operacional, Python, dependências)
- Container: instância em execução de uma imagem
- Dockerfile: arquivo de instruções para construir uma imagem
- docker-compose.yml: arquivo que define múltiplos containers e como eles se conectam
Primeiro Dockerfile para Python
Crie um projeto simples com uma aplicação Flask:
meu-projeto/
app.py
requirements.txt
Dockerfile
O app.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return {'mensagem': 'Ola do Docker!'}
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
O requirements.txt:
flask==3.1.0
gunicorn==23.0.0
Agora o Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
Cada linha do Dockerfile é uma instrução:
FROM: define a imagem base (Python 3.12 na versão slim, mais leve)WORKDIR: define o diretório de trabalho dentro do containerCOPY requirements.txt .: copia apenas o requirements primeiro (otimiza cache)RUN pip install: instala as dependênciasCOPY . .: copia o restante do códigoEXPOSE: documenta a porta usadaCMD: comando executado quando o container inicia
Construindo e executando
# Construir a imagem
docker build -t meu-projeto .
# Executar o container
docker run -p 5000:5000 meu-projeto
Acesse http://localhost:5000 e verá a resposta JSON da aplicação.
O arquivo .dockerignore
Crie um .dockerignore para evitar copiar arquivos desnecessários:
venv/
__pycache__/
*.pyc
.git/
.env
*.md
.pytest_cache/
Isso reduz o tamanho da imagem e acelera o build.
Docker Compose para múltiplos serviços
Aplicações reais geralmente precisam de banco de dados, cache e outros serviços. O docker-compose orquestra tudo isso.
Crie o docker-compose.yml:
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/app
environment:
- DATABASE_URL=postgresql://usuario:senha@db:5432/meu_banco
depends_on:
- db
- redis
db:
image: postgres:16
environment:
POSTGRES_USER: usuario
POSTGRES_PASSWORD: senha
POSTGRES_DB: meu_banco
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Inicie todos os serviços:
docker compose up -d
Comandos úteis do docker-compose:
# Ver logs
docker compose logs -f web
# Parar tudo
docker compose down
# Reconstruir após mudanças no Dockerfile
docker compose up --build
# Executar comando dentro do container
docker compose exec web python manage.py migrate
Multi-stage build
Para imagens de produção menores, use multi-stage build:
# Estagio 1: Build
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
# Estagio 2: Producao
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /install /usr/local
COPY . .
RUN useradd --create-home appuser
USER appuser
EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
Isso cria uma imagem final que contém apenas o necessário para rodar a aplicação, sem ferramentas de build.
Dockerfile para Django
Para projetos Django, o Dockerfile precisa de alguns ajustes:
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /app
RUN apt-get update && apt-get install -y \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN python manage.py collectstatic --noinput
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "config.wsgi:application"]
As variáveis de ambiente PYTHONDONTWRITEBYTECODE e PYTHONUNBUFFERED são boas práticas para containers Python. A primeira evita arquivos .pyc desnecessários e a segunda garante que os logs apareçam em tempo real.
Variáveis de ambiente e segredos
Nunca coloque senhas diretamente no Dockerfile ou docker-compose.yml. Use arquivos .env:
# .env (nao commitar no git!)
DATABASE_URL=postgresql://usuario:senha@db:5432/meu_banco
SECRET_KEY=minha-chave-secreta
DEBUG=False
No docker-compose.yml:
services:
web:
build: .
env_file:
- .env
Boas práticas
- Use imagens
slimoualpinepara reduzir o tamanho - Copie
requirements.txtantes do código para aproveitar o cache de layers - Crie um usuário não-root para rodar a aplicação
- Defina
PYTHONDONTWRITEBYTECODE=1ePYTHONUNBUFFERED=1 - Use
.dockerignorepara excluir arquivos desnecessários - Fixe versões das dependências no requirements.txt
- Use health checks no docker-compose para verificar se os serviços estão saudáveis
Conclusão
Docker simplifica o desenvolvimento e deploy de aplicações Python, eliminando problemas de “funciona na minha máquina”. Com Dockerfiles otimizados e docker-compose, você pode configurar ambientes complexos com poucos comandos. A curva de aprendizado inicial é compensada pela consistência e facilidade de deploy que o Docker proporciona em qualquer ambiente.