Health checks e readiness probes em containers Docker para Node.js: passo a passo
Por John Pires · 08 de março de 2026

Health checks e readiness probes em containers Docker para Node.js: passo a passo
1) Por que aprender isso em 2026
O problema que resolve
Aplicacoes em containers sao replicaveis e moveis, mas sem verificacoes ativos elas falham de maneiras silenciosas: processos travam, dependencias externas estouram e orquestradores mantem instancias inutilizaveis no ar. Health checks e readiness probes permitem detetar e reagir automaticamente a falhas, reduzindo tempo de indisponibilidade e melhorando o comportamento em producao.
Contexto 2026: orquestradores e CI/CD
Em 2026, implantar containers continua sendo padrao. Kubernetes, Docker Swarm e pipelines CI/CD (GitHub Actions, GitLab CI) assumem que containers informem seu estado. Saber como expor endpoints de saude no Node.js e configurar probes em Dockerfile, docker-compose e manifestos Kubernetes e pipeline de CI e essencial para qualquer engenheiro DevOps ou desenvolvedor backend.
Resultado pratico: com probes basicas voce consegue que um orchestrator remova pods com falha, que CI pare o deploy se a app nao subir corretamente e que sistemas de monitoramento alertem so quando realmente necessario.
Tip: probes nao substituem logs e metrics. Elas sao sinais booleanos simples pensados para controle de ciclo de vida do container.
2) Configuracao do ambiente
Ferramentas que vamos usar
Para seguir os passos precisa de: Docker (desktop ou engine), Node.js 18+, npm/yarn, curl (ou httpie) e opcionalmente um cluster Kubernetes (minikube, kind). Para CI usaremos GitHub Actions como exemplo. Instale localmente o Docker e o Node.js para testes antes de migrar para um cluster.
Estrutura do projeto
Vamos criar um projeto pequeno com: package.json, app.js, um Dockerfile, docker-compose.yml e um exemplo de manifest Kubernetes. A estrutura basica:
- package.json
- app.js
- Dockerfile
- docker-compose.yml
- k8s/deployment.yml
Crie uma pasta vazia e inicialize npm com npm init -y. Em seguida instale express: npm install express. Esses comandos assumem que voce esta em um terminal com Node.js instalado.
3) Hello World progressivo
Node.js com endpoints de health e readiness
Primeiro passo: o servidor Node.js deve expor dois endpoints claros: /healthz (liveness) e /ready (readiness). Liveness responde se o processo esta vivo. Readiness responde se a aplicacao esta apta a receber trafego (conexoes a banco, caches prontos, dependencias saudaveis).
Crie um arquivo app.js com um exemplo simples que simula dependencias. O codigo abaixo cria dois endpoints e um mecanismo para simular que a aplicacao so fica pronta apos um timeout para ilustrar probes.
// app.js
const express = require('express')
const app = express()
const port = process.env.PORT || 3000
let ready = false
// Simula inicializacao de dependencia assincrona
setTimeout(() => {
ready = true
console.log('Dependencias prontas, app pronta para receber trafego')
}, 5000)
app.get('/healthz', (req, res) => {
// Liveness: processo vivo? basta responder 200
res.status(200).send('ok')
})
app.get('/ready', (req, res) => {
// Readiness: depende de variavel ready
if (ready) return res.status(200).json({ ready: true })
return res.status(503).json({ ready: false })
})
app.get('/', (req, res) => {
res.send('app principal: respondendo')
})
app.listen(port, () => {
console.log(`Server listening on port ${port}`)
})
O que esse bloco faz: cria um servidor express que retorna 200 em /healthz enquanto o processo estiver vivo e 503 em /ready ate que as dependencias sejam consideradas prontas.
Depois de executar node app.js localmente, voce deve ver a mensagem de inicializacao e poder testar com curl localhost:3000/ready que inicialmente retorna 503 e, apos 5s, passa a 200.
Dockerfile com healthcheck embutido
Agora empacotamos em um container. Docker tem instrucao HEALTHCHECK que permite ao engine executar um comando para verificar se o container esta vivo. Para comportamento de readiness no nivel do orchestrador, preferimos que o processo exponha endpoints e o orchestrador (docker-compose ou k8s) faça as probes.
# Dockerfile
FROM node:18-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
HEALTHCHECK --interval=10s --timeout=3s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:3000/healthz || exit 1
CMD ["node", "app.js"]
O que esse Dockerfile faz: instala dependencias, expoe a porta e define um HEALTHCHECK que usa wget para acessar /healthz. Se o comando falhar repetidas vezes o Docker marca o container como unhealthy.
Teste localmente com:
docker build -t node-health-example .
docker run -p 3000:3000 --name node-health node-health-example
Depois, rode docker ps e docker inspect --format='{{json .State}}' node-health para ver o estado health. Durante os primeiros 5s a probe deve reportar healthy apos o start-period.
4) Mini-projeto pratico
docker-compose com healthcheck e dependencia de serviço
Vamos compor um exemplo com um serviço que depende de um banco (simulado por um serviço dummy). Usaremos docker-compose para demonstrar ordem de start e condicionais simples.
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- '3000:3000'
depends_on:
- dummydb
healthcheck:
test: [ 'CMD', 'wget', '-qO-', 'http://localhost:3000/healthz' ]
interval: 10s
timeout: 5s
retries: 3
environment:
- DUMMYDB_HOST=dummydb
dummydb:
image: alpine
command: sh -c "sleep 3000"
healthcheck:
test: [ 'CMD-SHELL', 'echo ok' ]
interval: 30s
O que acontece aqui: dummydb e um container que literalmente dorme (simulando dependencia). app depende de dummydb para iniciar, mas a readiness do app continua sendo determinada pelo endpoint /ready e pelo HEALTHCHECK da service. Note que docker-compose only honoured depends_on para ordem de start, nao para readiness — composable nao bloqueia ate que healthcheck de dependencia esteja healthy em todas as versoes, entao planeje isso.
Manifeste Kubernetes com liveness e readiness
Em Kubernetes voce deve configurar probes diretamente no spec do container. Exemplo abaixo mostra como configurar livenessProbe e readinessProbe usando HTTP GET. Isso permite que o kubelet reinicie o container quando necessario e que Services so encaminhem trafego para pods prontos.
# k8s/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: node-health-deploy
spec:
replicas: 2
selector:
matchLabels:
app: node-health
template:
metadata:
labels:
app: node-health
spec:
containers:
- name: node-health
image: node-health-example:latest
ports:
- containerPort: 3000
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 2
periodSeconds: 3
failureThreshold: 5
livenessProbe:
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
O que acontece quando aplica esse manifest: o kubelet usa readiness para decidir se o pod recebe trafego e liveness para reiniciar containers travados. Note que readiness tem initialDelay menor para detectar disponibilidade mais rapida, enquanto liveness usa intervalo maior para evitar reinicios desnecessarios.
CI/CD: GitHub Actions checando health antes de promover artefato
Um passo comum em pipelines e garantir que a imagem constrida responde ao health check antes de subir para registries ou promover para ambientes superiores. Exemplo basico de job que constrói imagem, executa container e aguarda healthcheck com curl.
# .github/workflows/health-check.yml (trecho)
name: build-and-test-health
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t node-health:ci .
- name: Run container
run: docker run -d --name node-health-ci -p 3000:3000 node-health:ci
- name: Wait for readiness
run: |
for i in $(seq 1 20); do
if curl -sSf http://localhost:3000/ready >/dev/null 2>&1; then
echo 'ready'
exit 0
fi
echo 'waiting...'
sleep 2
done
echo 'readiness timed out' && exit 1
Esse job falha se a readiness nao for atingida em tempo util, protegendo ambientes seguintes de deploy com uma imagem que nao esta funcional.
Erros comuns e dicas praticas
1. Health endpoint que faz trabalho pesado
Armadilha: implementar checks profundos e caros no endpoint de health. Probes devem ser rapidas e deterministicas. Se precisar rodar verificacoes pesadas, exponha um endpoint separado ou crie um job de verificacao assíncrona.
2. Confiar apenas no Docker HEALTHCHECK
O Docker HEALTHCHECK eh util para o engine local, mas orquestradores como Kubernetes ignoram o HEALTHCHECK do Dockerfile. Em K8s configure liveness/readiness no manifesto. Nao confie apenas no Dockerfile quando usar K8s.
Mais dicas:
- Use status codes HTTP: 200 para ok, 503/500 para nao pronto ou falha.
- Configure initialDelay apropriadamente para evitar falso-positivos durante startup.
- Tenha metricas para entender porque uma readiness cai: logs, traces e metrics complementam probes.
Pratica: mantenha endpoints de probe simples. Se algo complexo falhar, exponha um indicador simples que reflita o estado consolidado.
5) Recursos para continuar estudando
Documentacao oficial e guias
Leia documentacao oficial do Docker sobre HEALTHCHECK e a documentacao do Kubernetes sobre livenessProbe e readinessProbe. Esses guias explicam parametros e o comportamento em cada runtime.
Tutorials e ferramentas
Explore: kubelet probe examples, docker-compose nuances e ferramentas de teste como kubeval para validar manifestos, e kind/minikube para criar clusters locais. Ferramentas de observabilidade (Prometheus, Grafana, Loki) ajudam a correlacionar probes e logs.
Recomendo praticar criando pipelines simples no GitHub Actions que constroem, rodam e validam probes automaticamente. Isso traz confiança no deploy continuo.
Conclusao pratica
Health checks e readiness probes sao pequenos contratos entre sua aplicacao e a infraestrutura. Implementar endpoints simples no Node.js, configurar HEALTHCHECK no Dockerfile e probes no Kubernetes e nas pipelines permite que o sistema detecte falhas rapidamente e reaja de forma automatizada. Isso reduz MTTR e melhora a confiabilidade.
Passos sequentialmente praticos para aplicar o que vimos:
- Expor /healthz e /ready no Node.js com respostas rapidas e deterministicas.
- Adicionar HEALTHCHECK no Dockerfile para feedback local e em CI.
- Configurar readiness e liveness no manifest de Kubernetes para controle fino.
- Adicionar etapa de verificacao de readiness nos pipelines (GitHub Actions).
Voce agora tem um fluxo de trabalho completo: codigo que expoe probes, container que reporta health e orquestrador que decide quando reiniciar ou rotear trafego. Em producao, combine isso com logs estruturados e metricas para diagnostico rapido.
Terminando: implemente probes pequenas, padronize respostas HTTP e configure tempos coerentes com o tempo real de inicializacao de suas dependencias. Assim voce evita reinicios desnecessarios e garante que o trafego sempre passe para instancias aptas.
Assuntos: Node.js, Docker, Kubernetes, github-actions
Leia também
Paralelizando resolvers CPU-bound no Apollo/GraphQL com Worker Threads e pool
Evite bloqueio do event loop em resolvers CPU-bound no Apollo/GraphQL usando worker_threads com pool. Guia prático com implementação, integração com Apollo…
Processando CSVs grandes com Node.js Streams sem estourar memória
Guia passo a passo para processar CSVs grandes em Node.js sem estourar memória: exemplos práticos com streams, csv-parse, readline e worker threads, focado em…
Processar uploads CSV grandes com Streams, Worker Threads e progresso via SSE em Node.js
Processar CSV grandes sem travar o Node: mostro o jeito errado (ler tudo) e a solução correta com streams, worker threads e SSE para progresso em tempo real…
Abortar pipelines de Streams em Node.js: AbortController, timeouts e limpeza de Workers
Guia prático para abortar pipelines de streams em Node.js: uso de AbortController, patterns de timeout, e limpeza segura de Worker Threads para evitar…
Diagnóstico de latência em APIs Node.js com async_hooks, event-loop e GC
Diagnostique latência em APIs Node.js combinando async_hooks/AsyncLocalStorage, monitorEventLoopDelay e análise de GC. Passo a passo prático: medir…
Gerar thumbnails e checksums de uploads usando Streams e Worker Threads no Node.js
Como gerar thumbnails e checksums de uploads sem sobrecarregar o Node: padrões com Streams (PassThrough/pipeline) e offload para Worker Threads. Boas…