YAML para Docker Compose: Padrões de Configuração e Dicas
O Docker Compose utiliza YAML para definir aplicações multi-contentor. Um docker-compose.yml bem estruturado é a diferença entre um ambiente de desenvolvimento fluido e horas a depurar problemas de contentores. Este guia aborda padrões essenciais e armadilhas comuns.
Estrutura Básica
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- api
api:
build: ./api
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://db:5432/myapp
depends_on:
- db
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: myapp
POSTGRES_PASSWORD: secret
volumes:
pgdata:
Variáveis de Ambiente
Em Linha
services:
api:
environment:
NODE_ENV: production
PORT: "3000"
DEBUG: "false"
A Partir de Ficheiro
services:
api:
env_file:
- .env
- .env.local # Sobrepõe os valores do .env
Substituição de Variáveis
Referencie variáveis de ambiente do anfitrião:
services:
api:
image: myapp:${TAG:-latest} # Predefinição para "latest"
environment:
API_KEY: ${API_KEY} # Obrigatório - falha se não definido
LOG_LEVEL: ${LOG_LEVEL:-info} # Predefinição para "info"
Rede
Redes Personalizadas
services:
web:
networks:
- frontend
api:
networks:
- frontend
- backend
db:
networks:
- backend
networks:
frontend:
backend:
internal: true # Sem acesso externo
Os serviços na mesma rede podem comunicar entre si pelo nome do serviço. O serviço db é acessível apenas a partir do api, não a partir do web.
Mapeamento de Portas
ports:
- "8080:80" # anfitrião:contentor
- "443:443"
- "127.0.0.1:3000:3000" # Vincular apenas a localhost
- "3000" # Porta aleatória do anfitrião
Volumes
Volumes Nomeados (Persistentes)
services:
db:
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
driver: local
Montagens de Ligação (Desenvolvimento)
services:
api:
volumes:
- ./src:/app/src # Código-fonte
- /app/node_modules # Volume anónimo (prevenir sobreposição)
O padrão de volume anónimo (/app/node_modules) impede que a montagem de ligação do anfitrião sobreponha as dependências instaladas no contentor.
Verificações de Saúde
services:
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
api:
depends_on:
db:
condition: service_healthy
Isto garante que o api só inicia após o db passar nas verificações de saúde — não apenas quando o contentor arranca.
Campos de Extensão (Padrões DRY)
Utilize campos com prefixo x- com âncoras YAML para reduzir a repetição:
x-common: &common
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
x-env: &common-env
TZ: UTC
LOG_FORMAT: json
services:
api:
<<: *common
build: ./api
environment:
<<: *common-env
PORT: "3000"
worker:
<<: *common
build: ./worker
environment:
<<: *common-env
QUEUE: default
Para saber mais sobre âncoras YAML, consulte o nosso guia de âncoras e aliases YAML.
Compose Multi-Etapa
Desenvolvimento vs Produção
# docker-compose.yml (base)
services:
api:
build: ./api
environment:
DATABASE_URL: postgres://db:5432/myapp
# docker-compose.override.yml (dev - carregado automaticamente)
services:
api:
volumes:
- ./api/src:/app/src
environment:
NODE_ENV: development
DEBUG: "true"
ports:
- "3000:3000"
- "9229:9229" # Porta de depuração
# docker-compose.prod.yml
services:
api:
environment:
NODE_ENV: production
deploy:
replicas: 3
# Desenvolvimento (carrega o override automaticamente)
docker compose up
# Produção
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
Armadilhas Comuns
1. Números de Porta Sem Aspas
# ARRISCADO - YAML interpreta 80:80 como um número em base 60
ports:
- 80:80
# SEGURO - coloque sempre aspas
ports:
- "80:80"
2. Variáveis de Ambiente Booleanas
# ERRADO - YAML converte para booleano
environment:
DEBUG: true # Torna-se Python True, não a string "true"
# CORRETO - coloque aspas em todos os valores de ambiente
environment:
DEBUG: "true"
3. Temporização do depends_on
O depends_on apenas aguarda pelo arranque do contentor, não pela prontidão:
# O contentor arranca mas a BD pode não estar pronta
depends_on:
- db
# Aguardar pela verificação de saúde
depends_on:
db:
condition: service_healthy
Valide os seus ficheiros Docker Compose com o nosso Validador YAML.
FAQ
Qual é a diferença entre docker-compose.yml e compose.yml?
Ambos os nomes de ficheiro funcionam. compose.yml é a convenção mais recente recomendada pelo Docker. docker-compose.yml é o nome legado. O Docker Compose v2+ procura ambos, preferindo compose.yml se ambos existirem. Para novos projetos, utilize compose.yml.
Devo utilizar o Docker Compose em produção?
O Docker Compose é excelente para desenvolvimento e implementações simples. Para produção em escala, considere o Docker Swarm (utiliza ficheiros Compose nativamente) ou Kubernetes. A vantagem do Compose é que a sua configuração de desenvolvimento informa diretamente a produção, reduzindo diferenças entre ambientes.
Recursos Relacionados
- Validador YAML — Valide YAML do Docker Compose
- Âncoras e Aliases YAML — Padrões de configuração DRY
- Tutorial de Sintaxe YAML — Fundamentos de YAML