
depends_on não espera o banco — use healthcheck para evitar a corrida

Para fazer o Docker Compose esperar o banco, defina um healthcheck no serviço do banco e use condition: service_healthy em depends_on na aplicação. A documentação do Docker sobre a ordem de partida distingue contêiner em execução de serviço pronto: a dependência simples respeita a ordem, mas pode liberar a aplicação antes de o banco aceitar consultas.
O comando do healthcheck precisa representar a operação necessária para a partida. No exemplo abaixo, o PostgreSQL só recebe o estado healthy depois que uma consulta SQL ao banco indicado devolve o resultado esperado. A aplicação, então, faz sua própria conexão ao serviço db pela rede do Compose.
Um exemplo reproduzível com banco e aplicação

Este exemplo é demonstrativo: app usa o cliente PostgreSQL para representar a primeira consulta de uma aplicação. Salve a linha a seguir em um arquivo chamado compose.yaml. A senha demo serve apenas para reproduzir o comportamento em ambiente local.
compose.yaml: services: {db: {image: "postgres:16", environment: {POSTGRES_USER: demo, POSTGRES_PASSWORD: demo, POSTGRES_DB: demo}, healthcheck: {test: ["CMD-SHELL", "PGPASSWORD=demo psql -h 127.0.0.1 -U demo -d demo -tAc 'SELECT 1' | grep -qx 1"], interval: 5s, timeout: 3s, retries: 5, start_period: 20s}}, app: {image: "postgres:16", environment: {PGPASSWORD: demo}, command: ["psql", "-h", "db", "-U", "demo", "-d", "demo", "-tAc", "SELECT 1"], depends_on: {db: {condition: service_healthy}}}}
A notação compacta entre chaves é YAML válido; o arquivo inteiro ocupa uma linha para caber nos elementos disponíveis nesta página. Execute docker compose up -d e consulte docker compose logs app. O resultado esperado no log é 1: app executa uma consulta e termina, em vez de permanecer como um servidor. Use docker compose ps -a para conferir seu estado de saída e docker compose down para remover os contêineres ao terminar.
Dentro de db, o teste tenta uma conexão TCP em 127.0.0.1, acessa o banco demo como usuário demo e exige que a saída da consulta seja exatamente 1. O operador de pipe entrega a saída de psql ao grep; se a resposta não corresponder, o healthcheck falha. Já app usa o endereço db, resolvido na rede do Compose. Ao adaptar o exemplo, mantenha o comando normal da sua aplicação e acrescente a dependência condicionada; o cliente que termina após uma consulta existe apenas para mostrar o resultado.
O que o teste precisa provar
Uma porta aberta pode ser insuficiente quando a primeira operação exige um banco específico ou uma consulta. Escolha a menor operação que precisa funcionar antes de iniciar a aplicação. SELECT 1 demonstra que uma consulta foi executada no banco indicado, mas não demonstra que tabelas, extensões ou dados exigidos pelo serviço já existem.
A documentação do pg_isready explica que a ferramenta verifica se o servidor aceita conexões mesmo quando usuário, senha ou nome do banco informados estão incorretos. Ela basta quando esse é o critério de prontidão. Se a partida depende de uma consulta no banco escolhido, psql oferece um teste mais próximo dessa necessidade.
Se migrações executadas por outro serviço precisam terminar antes da aplicação, o teste pode consultar uma tabela criada por elas. Se a própria aplicação executa as migrações ao iniciar, exigir essa tabela no healthcheck do banco criaria uma espera circular: app aguardaria uma condição que só poderia produzir depois de iniciar. Nesse caso, mantenha o teste do banco limitado ao que já deve estar disponível antes das migrações.
O healthcheck roda dentro de db, enquanto app se conecta pelo nome db. Por isso, uma consulta local bem-sucedida não comprova sozinha o caminho de rede, a configuração de conexão nem a operação feita pela aplicação. A tentativa de app no exemplo torna essa distinção visível sem atribuir ao estado healthy uma garantia maior do que o teste realmente oferece.
Como ajustar período inicial, intervalo, timeout e tentativas
Os valores do exemplo são ilustrativos. A referência de HEALTHCHECK do Docker define os estados starting, healthy e unhealthy e descreve como interval, timeout, retries e start_period afetam as verificações. Ajuste esses parâmetros ao tempo de inicialização do banco e à duração normal da operação escolhida.
- test: é o comando que determina o resultado. No exemplo, psql executa SELECT 1 e grep aceita apenas a saída 1. Uma falha de conexão, de consulta ou de comparação impede que o teste seja considerado bem-sucedido.
- interval: determina o espaçamento entre verificações após o período inicial. Um intervalo menor permite detectar a prontidão mais cedo, mas executa a consulta com maior frequência; um intervalo maior pode retardar a partida de app depois que db já responde.
- timeout: limita a duração de cada tentativa. Deve comportar uma resposta normal da consulta sem deixar uma tentativa travada prolongar a espera.
- start_period: dá margem para a inicialização. Falhas nesse período não entram na contagem de retries, mas um teste que passa antes de seu término já pode marcar db como saudável. Portanto, ele não funciona como atraso mínimo para app.
- retries: indica quantas falhas consecutivas são necessárias para marcar o contêiner como unhealthy. Aumentar o valor tolera falhas transitórias, mas também adia a identificação de um banco que continua indisponível.
Observe a inicialização com o conjunto real de dados e scripts, além do tempo de uma consulta saudável. Reserve start_period para a fase de preparação esperada, timeout para cada tentativa e interval com retries para a tolerância posterior. Multiplicar interval por retries não produz um prazo exato: cada verificação também consome tempo, e as falhas durante o período inicial seguem uma regra própria.
Diagnóstico: iniciado, saudável e pronto para a aplicação

O estado de db mostra o resultado do teste feito dentro do banco; o estado de app mostra o que aconteceu com a conexão do serviço dependente. Leia os dois em conjunto:
- db em execução; saúde starting: o processo iniciou, mas o teste ainda não passou. App aguarda a condição. Consulte docker compose ps e os logs de db para acompanhar a inicialização.
- db unhealthy: o teste acumulou falhas suficientes. Confira se psql e grep existem na imagem usada, se o comando funciona dentro de db e se usuário e banco correspondem à configuração.
- db healthy; app encerrou com sucesso: o teste local passou e a consulta de app também funcionou. Esse é o resultado esperado do cliente demonstrativo, criado para executar uma operação e sair.
- db healthy; app falhou: a consulta local passou, mas a conexão ou operação de app não. Compare no log de app o endereço, o banco, as credenciais e a consulta antes de alterar os tempos do healthcheck.
- db healthy; app continua em execução, mas não atende: a condição de partida do banco foi satisfeita. Verifique separadamente a função que a aplicação oferece aos usuários; o teste de db não mede essa prontidão.
Ao substituir o cliente demonstrativo pelo serviço real, preserve a diferença entre as duas verificações: o healthcheck define quando o banco está pronto para a dependência escolhida, e a aplicação precisa lidar com o resultado da própria conexão.
Leia também:
Artigos relacionados


Gateways de IA viraram alvo: Microsoft viu roubo de chaves e mineração

Carbonato põe um agente de IA no Docker exposto para roubar chaves

Kit MCP pode alterar sua lista: como limitar permissões antes de conectar a IA

Seu RAG responde certo pelo motivo errado — meça contexto e fidelidade

PIN, senha e código do WhatsApp não são iguais — proteja a conta sem se bloquear
Assine nossa newsletter
Receba as últimas notícias sobre Web3, IA e cripto diretamente no seu e-mail.