Docker Compose na Prática: Criando Ambientes com Múltiplos Containers
Docker Compose na Prática: Criando Ambientes com Múltiplos Containers
Introdução
Gerenciar um único container é simples, mas aplicações reais geralmente dependem de múltiplos serviços (banco de dados, cache, fila, front‑end). O Docker Compose resolve esse problema ao permitir declarar, configurar e orquestrar grupos de containers através de um único arquivo YAML. Este artigo destina‑se a desenvolvedores, administradores de sistemas e entusiastas de homelab que já conhecem Docker e desejam evoluir para ambientes compostos.
O que você vai aprender
- Por que Docker Compose é necessário para projetos multi‑container.
- Estrutura completa de
compose.yaml(services, networks, volumes). - Uso de healthchecks e restart policies.
- Configuração de variáveis de ambiente via
.enveenv_file. - Estratégias de dependência com
depends_one condições de saúde. - Criação de um stack WordPress + MySQL + Adminer.
- Manipulação de volumes nomeados e redes customizadas.
- Laboratório completo e reproduzível.
- Troubleshooting de portas, healthchecks e variáveis.
Pré‑requisitos
- Ubuntu 22.04 LTS com Docker Engine instalado (veja o artigo Docker no Linux).
- Usuário com permissão para executar
docker(grupodocker). - Conexão à internet para baixar imagens oficiais.
- Editor de texto (vim, nano ou VS Code).
Conceitos fundamentais
| Conceito | Definição |
|---|---|
| Compose file | Arquivo YAML que descreve serviços, redes e volumes. |
| Service | Um container gerenciado pelo Compose. |
| Network | Rede Docker onde os serviços podem comunicar‑se por nome. |
| Volume | Persistência de dados fora do ciclo de vida do container. |
| Healthcheck | Teste que determina se o container está saudável; usado por depends_on. |
depends_on |
Declara dependência entre serviços; opcionalmente aguarda health. |
.env |
Arquivo de variáveis de ambiente interpoladas no compose file. |
env_file |
Arquivo externo carregado como variáveis de ambiente. |
Preparação do ambiente
- Criar diretório do projeto
mkdir -p $HOME/docker-compose-lab && cd $HOME/docker-compose-lab
Resultado esperado: Diretório vazio pronto para receber arquivos.
2. Criar.envcom credenciais do MySQL
cat > .env <<'EOF'
MYSQL_ROOT_PASSWORD=StrongRootPass123!
MYSQL_DATABASE=wpdb
MYSQL_USER=wpuser
MYSQL_PASSWORD=WpPass123!
EOF
Resultado esperado: Arquivo
.envcriado com as variáveis.
3. Criardocker-compose.yaml(ver seção abaixo).
Estrutura completa do compose.yaml
version: "3.9"
services:
db:
image: mysql:8.0
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
wordpress:
image: wordpress:6.5-php8.2-apache
depends_on:
db:
condition: service_healthy
restart: unless-stopped
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: ${MYSQL_USER}
WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
WORDPRESS_DB_NAME: ${MYSQL_DATABASE}
ports:
- "8080:80"
volumes:
- wp_data:/var/www/html
networks:
- backend
- frontend
adminer:
image: adminer:latest
restart: unless-stopped
ports:
- "8081:8080"
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true
volumes:
db_data:
wp_data:
Explicação linha a linha
– version – Versão do schema Compose (3.9 oferece recursos avançados).
– services.db – Container MySQL com variáveis interpoladas do .env.
– healthcheck – Garante que o MySQL esteja pronto antes do WordPress iniciar.
– depends_on com condition: service_healthy – WordPress aguarda MySQL saudável.
– networks.backend marcado como internal impede acesso externo direto ao banco.
– networks.frontend permite que o WordPress exponha a porta 8080 ao host.
– volumes nomeados (db_data, wp_data) preservam dados entre recriações.
Tutorial passo a passo
Etapa 1 – Levantar o stack
docker compose up -d
Resultado esperado: Containers
docker-compose-lab_db_1,docker-compose-lab_wordpress_1,docker-compose-lab_adminer_1em estado Up.
Etapa 2 – Verificar saúde dos serviços
docker compose ps
Resultado esperado: Coluna State mostra
healthyparadberunningpara WordPress.
Etapa 3 – Acessar WordPress
Abra o navegador em http://localhost:8080 e conclua a instalação padrão.
Etapa 4 – Gerenciar o banco via Adminer
Acesse http://localhost:8081, use as credenciais definidas no .env.
Etapa 5 – Parar e remover o ambiente sem perder dados
docker compose down -v # remove containers e redes, mantém volumes
Resultado esperado: Containers e redes são removidos, mas volumes
db_dataewp_datapermanecem.
Etapa 6 – Recriar o ambiente reutilizando os volumes
docker compose up -d
WordPress carrega a base de dados previamente criada, permitindo continuação.
Laboratório completo
Reproduza o laboratório inteiro seguindo os passos acima. Verifique:
– A aplicação WordPress persiste após down -v (dados permanecem).
– O healthcheck realmente impede que o WordPress tente conectar ao MySQL antes que ele esteja pronto (observe logs de docker compose logs wordpress).
– As redes frontend e backend isolam o tráfego como esperado (tente docker exec -it <container> ping db).
Troubleshooting: problemas comuns e como resolver
1. Sintoma – Port already allocated: 8080.
- Possível causa: Outro serviço (Apache, Nginx) já usa a porta.
- Diagnóstico:
sudo lsof -i :8080. - Solução: Alterar o mapeamento de porta no
compose.yaml(ex.:"8082:80"). - Prevenção: Verificar uso de portas antes de iniciar o stack.
2. Sintoma – db nunca fica healthy.
- Possível causa: Credenciais incorretas ou conexão lenta ao disco.
- Diagnóstico:
docker compose logs dbpara ver falhas domysqladmin ping. - Solução: Ajustar
interval/retriesou garantir que a variávelMYSQL_ROOT_PASSWORDesteja correta. - Prevenção: Testar a imagem MySQL isoladamente antes de integrar.
3. Sintoma – Variáveis de ambiente não são lidas (environment vazio).
- Possível causa: Arquivo
.envnão está no mesmo diretório docompose.yaml. - Diagnóstico:
docker compose configexibe valores interpolados. - Solução: Mover
.envpara o diretório raiz ou especificarenv_fileexplicitamente. - Prevenção: Sempre rodar
docker compose configapós mudanças.
4. Sintoma – docker compose up falha com ERROR: No such file or directory: docker-compose.yaml.
- Possível causa: Nome do arquivo errado (deve ser
docker-compose.ymloucompose.yaml). - Diagnóstico:
lspara confirmar o nome. - Solução: Renomear para
docker-compose.ymlou usar a flag-f. - Prevenção: Padronizar o nome do arquivo no início do projeto.
Segurança
- Política de reinício –
restart: unless-stoppedevita que containers entrem em ciclo de crash. - Segurança de rede – Redes internas (
internal: true) impedem acesso externo ao banco. - Variáveis sensíveis – Não versionar
.env; armazenar em secret manager ou usardocker secret. - Imagem fixa – Defina versões específicas (
mysql:8.0.36,wordpress:6.5-php8.2-apache). - Least privilege – Use usuário não‑root dentro do container (
user: www-data).
Boas práticas
| Prática | Justificativa |
|---|---|
| Versionar o compose file | Garante reprodutibilidade em CI/CD. |
| Separar redes – frontend / backend | Isola serviços críticos de acesso público. |
| Healthcheck consistente | Permite orquestração confiável; evita “race condition”. |
| Volumes nomeados | Dados persistem independentemente de recriações. |
docker compose config antes de up |
Detecta erros de sintaxe e interpolação. |
Limitar recursos – mem_limit, cpus |
Evita consumo excessivo em ambientes compartilhados. |
Comparação Docker Compose vs Docker Swarm (quando houver confusão)
| Aspecto | Docker Compose | Docker Swarm |
|---|---|---|
| Escopo | Máquina única (ou host com Docker). | Cluster multi‑host. |
| Orquestração | Declarativa, via docker compose up. |
Declarativa + serviço distribuído (docker swarm init). |
| Load balancing | Não nativo (necessita de proxy externo). | Integrado (routing mesh). |
| Escalabilidade | docker compose up --scale (limitado ao host). |
docker service scale (across nodes). |
| Persistência | Volumes locais; bind ou named. | Volumes distribuídos via plugins (e.g., NFS). |
| Uso típico | Desenvolvimento, teste, pequenos prod. | Produção em larga escala. |
Conclusão
Docker Compose simplifica a orquestração de múltiplos containers, permitindo que desenvolvedores descrevam infraestrutura como código em um único arquivo YAML. Ao dominar healthchecks, dependências e redes, você cria ambientes robustos, reproduzíveis e seguros, prontos para avançar rumo a orquestradores de cluster como Kubernetes ou Docker Swarm.
Perguntas frequentes
P1: Posso usar docker compose sem o Docker Engine instalado?
R: Não. O Compose depende do daemon Docker; instale o Docker Engine primeiro (veja o artigo Docker no Linux).
P2: Qual a diferença entre depends_on simples e com condition: service_healthy?
R: O primeiro inicia os containers na ordem declarada, sem aguardar saúde. O segundo espera o healthcheck do serviço dependente reportar healthy antes de iniciar o dependente.
Próximo passo
Agora que você domina Docker Compose Na Pratica, o próximo passo lógico da nossa trilha de aprendizado é continuar desenvolvendo suas habilidades.
→ Continue: Nginx e Reverse Proxy no Linux
Artigos relacionados
Estes artigos complementam o conteúdo apresentado:
