Olá! Bem-vindo de volta ao nosso curso.
Introdução
Na lição anterior, você aprendeu a usar a propriedade depends_on com condições como service_healthy para orquestrar a ordem de inicialização dos seus serviços. Vimos que simplesmente garantir que um contêiner de banco de dados inicie antes da sua API não é suficiente; precisamos garantir que ele esteja pronto para aceitar conexões.
Nesta lição, vamos nos aprofundar no mecanismo que torna isso possível: a diretiva healthcheck. Você aprenderá a implementar verificações de saúde personalizadas em seus serviços no Docker Compose. Isso lhe dará o poder de definir precisamente o que significa "saudável" para cada componente da sua aplicação, desde um banco de dados PostgreSQL até a sua API .NET. Ao final, você será capaz de construir sistemas multi-contêiner verdadeiramente robustos que iniciam de forma previsível e resiliente.
1. Anatomia de uma Verificação de Saúde (healthcheck)
A diretiva healthcheck é adicionada à definição de um serviço em seu arquivo docker-compose.yml. Ela instrui o Docker Engine a executar um comando específico periodicamente dentro do contêiner para verificar seu status. Se o comando retornar um código de saída 0, o serviço é considerado healthy. Se retornar um código diferente de 0, é uma falha.
Uma configuração completa de healthcheck possui várias opções que permitem um controle fino sobre seu comportamento.
Docker Compose Health Checks: An Easy-to-follow Guide
Para ter uma visão geral completa das opções de configuração do healthcheck, estude a seção correspondente neste guia do Last9.io.
Leia a seção "Set up Your First Docker Compose Health Check" e preste atenção especial à tabela "Health Check Options Explained". Isso lhe dará uma base sólida sobre o propósito de cada parâmetro.
Aqui está um resumo das opções que você acabou de ler:
| Opção | Propósito | Exemplo |
|---|---|---|
test |
O comando a ser executado para verificar a saúde do serviço. | ["CMD", "curl", "-f", "http://localhost/health"] |
interval |
O tempo de espera entre cada verificação de saúde. | 30s |
timeout |
O tempo máximo que o Docker esperará pela conclusão do comando. Se exceder, conta como falha. | 10s |
retries |
O número de falhas consecutivas necessárias para que o contêiner seja marcado como unhealthy. |
3 |
start_period |
Um período de carência após o contêiner iniciar, durante o qual as falhas na verificação de saúde não contam para o número de retries. Essencial para serviços que demoram a inicializar. |
60s |
O status de saúde de um contêiner passa pelos seguintes estados:
starting: O contêiner iniciou e ostart_periodestá ativo. Falhas são ignoradas.healthy: O comando detestretornou um código de saída0.unhealthy: O número deretriesde falhas consecutivas foi atingido.
2. Formatos do Comando test
A propriedade test pode ser definida em alguns formatos diferentes, o que é importante entender, pois afeta como o comando é executado.
How to Use Docker Compose depends_on with Health Checks
Para entender as nuances entre os formatos de teste, leia a seção "Test Formats" do artigo do OneUptime. A distinção entre CMD e CMD-SHELL é particularmente importante.
Concentre-se na subseção "Test Formats". Note como CMD-SHELL permite o uso de operadores de shell, como pipes (|) e &&.
Resumindo:
- Formato de string:
test: "curl -f http://localhost/health || exit 1". Este formato é um atalho paraCMD-SHELL. CMD-SHELL:test: ["CMD-SHELL", "curl -f http://localhost/health"]. O comando é executado dentro de um shell (/bin/sh -c), o que permite o uso de variáveis de ambiente do shell, pipes, etc.CMD:test: ["CMD", "curl", "-f", "http://localhost"]. O comando é executado diretamente, sem um shell. É um pouco mais eficiente e seguro, mas não permite funcionalidades do shell.
Na maioria das vezes, CMD é suficiente, mas se você precisar de lógicas mais complexas, como encadear comandos, CMD-SHELL é a ferramenta certa.
3. Exemplos Práticos para Serviços Comuns
A teoria é importante, mas a implementação prática é fundamental. A beleza dos health checks é que existem padrões bem estabelecidos para a maioria dos serviços que você usará. Dado seu background e seus objetivos, vamos focar em exemplos para uma API web, PostgreSQL e RabbitMQ.
Pré-requisito: Ferramentas no Contêiner
Um ponto crucial e uma fonte comum de erros: o executável usado no comando test (por exemplo, curl, pg_isready) deve estar disponível dentro da imagem do contêiner. Imagens mínimas, como alpine, muitas vezes não incluem essas ferramentas por padrão.
Se você precisar de curl em uma imagem baseada em Alpine, adicione esta linha ao seu Dockerfile:
RUN apk add --no-cache curl
Agora, vamos aos exemplos.
How to Use Docker Compose depends_on with Health Checks
Este artigo contém uma excelente "receita de bolo" com comandos de health check para uma variedade de serviços. Recomendo fortemente que você o leia para ter uma referência prática.
Leia a seção "Common Service Health Checks". Preste atenção especial aos exemplos para PostgreSQL, RabbitMQ e HTTP Services, pois eles são diretamente relevantes para o tipo de aplicação que você está construindo.
Com base no que você leu, aqui está um resumo para nossos serviços de interesse:
-
API Web (.NET): Para uma API que expõe um endpoint de saúde (por exemplo,
/healthz, uma prática comum com ASP.NET Core Health Checks),curlé a ferramenta perfeita.services: webapi: # ... healthcheck: test: ["CMD", "curl", "-f", "http://localhost:80/healthz"] interval: 10s timeout: 5s retries: 3 start_period: 30s -
PostgreSQL: A imagem oficial do Postgres já vem com a ferramenta
pg_isready, que foi projetada exatamente para este propósito.services: db: image: postgres:14 environment: POSTGRES_USER: myuser # ... healthcheck: test: ["CMD-SHELL", "pg_isready -U myuser -d postgres"] interval: 5s timeout: 5s retries: 5 start_period: 10s -
RabbitMQ: A imagem de gerenciamento do RabbitMQ inclui ferramentas de diagnóstico que podemos usar.
services: rabbitmq: image: rabbitmq:3-management healthcheck: test: ["CMD", "rabbitmq-diagnostics", "check_running", "-q"] interval: 10s timeout: 5s retries: 5 start_period: 30s
4. Juntando Tudo e Solucionando Problemas
Agora, vamos ver como um docker-compose.yml se parece com tudo isso integrado. Uma API depende de um banco de dados que tem seu próprio health check.
version: '3.8'
services:
webapi:
build: ./my-dotnet-api
ports:
- "8080:80"
depends_on:
db:
condition: service_healthy # Espera o banco de dados ficar saudável
db:
image: postgres:14-alpine
environment:
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mysecretpassword
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U myuser"]
interval: 5s
timeout: 5s
retries: 10
start_period: 10s
volumes:
postgres-data:
Ao executar docker-compose up, você verá os logs do contêiner db iniciando e, após alguns segundos, o contêiner webapi começará sua inicialização, exatamente como esperado.

Mas e se não funcionar?
Diagnosticando Falhas de Health Check
-
Verifique o Status: O comando
docker-compose ps(oudocker ps) mostrará o status de saúde dos seus contêineres na colunaSTATUS. Você verá algo como(healthy)ou(unhealthy). -
Inspecione o Contêiner: O comando
docker inspectfornece detalhes ricos sobre a falha.docker inspect <container_name_or_id>
Procure pela seçãoState.Health. Ela mostrará um log das últimas verificações de saúde, incluindo o código de saída e a saída do comando (stdout/stderr).

- Execute o Comando Manualmente: A melhor maneira de depurar é tentar executar o comando de teste você mesmo dentro do contêiner.
docker-compose exec <service_name> <your_test_command>
Por exemplo:docker-compose exec db pg_isready -U myuser
Docker Compose Tutorial for Beginners (Networks - Volumes - Secrets - Postgres - Letsencrypt)
Para ver uma demonstração simples de um health check sendo adicionado a um serviço web, assista a este clipe.
Assista do timestamp 53:52 a 55:34. O vídeo mostra a adição de um healthcheck usando curl em uma aplicação Flask e como o depends_on do serviço Nginx espera que o Flask se torne saudável.
Teste seu entendimento!
Você está trabalhando com o seguinte arquivo docker-compose.yml. A api depende do cache (Redis), mas atualmente não há nenhuma garantia de que o Redis esteja pronto quando a API iniciar.
Sua tarefa é modificar o arquivo para que:
- O serviço
cachetenha um health check apropriado usando o comandoredis-cli ping. Use umintervalde5s,retriesde5, e umstart_periodde10s. - O serviço
apiespere até que ocacheesteja saudável antes de iniciar.
version: '3.8'
services:
api:
build: .
ports:
- "5000:80"
depends_on:
- cache # <-- Precisa ser melhorado
cache:
image: redis:6-alpine
# TODO: Adicionar healthcheck aqui
Show answer
A solução correta é:
version: '3.8'
services:
api:
build: .
ports:
- "5000:80"
depends_on:
cache:
condition: service_healthy # Modificado para esperar a condição saudável
cache:
image: redis:6-alpine
healthcheck: # Adicionado o bloco de healthcheck
test: ["CMD", "redis-cli", "ping"]
interval: 5s
retries: 5
start_period: 10s
Explicação:
- Adicionamos o bloco
healthcheckao serviçocache. Ele usa oredis-cli ping, que é o método padrão para verificar a prontidão do Redis. - Alteramos o
depends_onno serviçoapipara o formato longo, especificandocondition: service_healthy. Isso instrui o Docker Compose a esperar que o health check docachepasse antes de iniciar aapi.
Conclusão
Excelente trabalho! Você agora tem o conhecimento prático para implementar verificações de saúde eficazes em suas aplicações Docker Compose. Isso eleva a robustez dos seus ambientes de desenvolvimento e teste a um novo patamar, eliminando condições de corrida e falhas de inicialização.
Principais Pontos:
- A diretiva
healthcheckpermite definir um comando para validar a prontidão de um serviço. - Parâmetros como
interval,timeout,retries, e especialmentestart_period, oferecem controle fino sobre o comportamento da verificação. - A combinação de um
healthcheckbem definido no serviço de dependência comdepends_on: condition: service_healthyno serviço dependente é a maneira canônica de garantir uma ordem de inicialização robusta. - A depuração de falhas de health check é feita principalmente com
docker-compose ps,docker inspect, e executando o comando de teste manualmente comdocker-compose exec.
Na próxima lição, vamos mudar nosso foco de robustez para segurança. Iniciaremos o módulo de Segurança de Contêineres e Boas Práticas, começando com um princípio fundamental: aplicar o princípio do menor privilégio, criando e executando contêineres como usuários não-root.