Container Docker reiniciando em loop: como diagnosticar e corrigir

Container em loop de reinicialização (restart loop) significa que ele inicia, falha e é reiniciado repetidamente pelo Docker. O diagnóstico começa com `docker logs <container>`, 90% das vezes a causa está ali. As causas mais comuns são: a aplicação crasha imediatamente (erro de código ou config), OOM (sem memória), variável de ambiente obrigatória ausente ou conflito de porta.

Passo 1: ler os logs do container

O primeiro passo é sempre ver o que o container está reportando antes de morrer:

bash
# Ver os últimos 50 logs (mesmo que o container esteja parado)
docker logs --tail 50 nome_do_container

# Seguir os logs em tempo real (Ctrl+C para parar)
docker logs -f nome_do_container

# Com docker-compose
docker compose logs --tail 50 nome_do_servico

Passo 2: inspecionar o estado do container

docker inspect mostra o estado detalhado, incluindo o código de saída (ExitCode) e se foi morto por OOM:

bash
# Ver estado completo do container
docker inspect nome_do_container | grep -A 10 '"State"'

# Procurar especificamente por OOM kill e código de saída
docker inspect nome_do_container | grep -E '"OOMKilled"|"ExitCode"'

Causas comuns e como corrigir

Os motivos mais frequentes de restart loop, em ordem de ocorrência:

Diagnóstico de OOM (falta de memória)

Para containers matados por falta de memória, verifique o uso atual antes de ajustar limites:

bash
# Ver uso de memória de todos os containers em tempo real
docker stats --no-stream

# Ou só de um container específico
docker stats --no-stream nome_do_container

# Configurar limite de memória no docker-compose.yml
services:
  minha-app:
    image: minha-imagem:latest
    deploy:
      resources:
        limits:
          memory: 512M   # mínimo recomendado
          cpus: '0.5'

Rodar o container em modo interativo para debug

Quando os logs não são suficientes, substitua o comando de entrada para abrir um shell dentro do container:

bash
# Substituir o entrypoint por bash para inspecionar o ambiente
docker run --rm -it --entrypoint /bin/bash nome_da_imagem

# Ou, se o container usa sh (imagens Alpine)
docker run --rm -it --entrypoint /bin/sh nome_da_imagem

# Verificar se as variáveis de ambiente estão chegando
docker run --rm -it --env-file .env --entrypoint /bin/sh nome_da_imagem
env | grep NOME_DA_VAR

Não quer configurar manualmente?

Implante o Docker em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

Use docker update --restart=no nome_do_container para remover a política de restart, depois docker stop. Assim você pode inspecionar sem ele reiniciar automaticamente. Depois de corrigir, restaure com docker update --restart=always.

As causas mais comuns de restart inesperado em container que estava saudável: disco cheio (container não consegue escrever logs/dados), atualização de imagem com breaking change, OOM por aumento de tráfego, ou alteração de variáveis de ambiente. Verifique df -h e os logs do Docker daemon com journalctl -u docker.

Use restart: on-failure no Compose (ou --restart=on-failure no docker run). O container reinicia apenas quando sai com código diferente de 0. Útil para jobs que devem parar ao concluir mas reiniciar em caso de erro.

depends_on garante ordem de startup, mas não garante que o serviço esteja pronto, só que o container iniciou. Para esperar que o serviço esteja realmente pronto, adicione um healthcheck no serviço dependente e use condition: service_healthy no depends_on do serviço que depende dele.

docker inspect nome_do_container | grep -E ""RestartCount"|"StartedAt"|"FinishedAt"" mostra o número de restarts e os timestamps de início e fim. Para histórico completo de eventos do Docker daemon, use docker events --since 1h.