Voltar ao Blog
HermesDockerTroubleshootingSelf-Hosting

Contêiner Docker do Hermes Agent reiniciando sem parar

Diagnostique por que o contêiner Docker do Hermes Agent fica reiniciando: OOM, .env inválido, permissões de volume, portas e imagem ARM.

Por Hermify Team||7 min de leitura
Terminal escuro mostrando um contêiner Docker do Hermes Agent em loop de reinício, com o exit code destacado em verde

Seu contêiner do Hermes Agent sobe, morre em poucos segundos e o Docker levanta de novo. O docker ps mostra a linha Restarting (137) 3 seconds ago, o bot não responde no Telegram e o hermes logs repete o mesmo banner de startup várias vezes. Esse loop quase sempre é um de cinco problemas bem específicos, e o exit code que o Docker imprime já te diz qual. Este post passa por cada um, na ordem que resolve mais agentes.

Se você ainda não rodou o contêiner, comece por como rodar o Hermes Agent no Docker primeiro. Este guia assume que a imagem baixa direitinho, que o compose está no lugar e que algo quebra no momento em que o processo sobe.

Passo 1 - Leia o exit code real antes de mexer em qualquer coisa

O Docker guarda o exit code da última execução dentro do estado do contêiner. Leia direto em vez de chutar pelos logs:

docker inspect --format='{{.State.ExitCode}} OOM={{.State.OOMKilled}} err={{.State.Error}}' hermes-agent

Essa única linha te dá três coisas de uma vez: o exit code, se o OOM killer do kernel matou o processo, e qualquer erro no nível do daemon que o Docker anexou ao run. O exit code já reduz muito a busca:

  • 137 - o processo recebeu SIGKILL. Quase sempre é um OOM kill por limite de memória do contêiner ou pelo host ficando sem RAM, ocasionalmente um docker stop que estourou os 10 segundos de graça.
  • 139 - falha de segmentação. No Hermes Agent isso aparece quando a arquitetura da imagem não bate com o host (imagem amd64 num VPS ARM, ou o inverso).
  • 125 / 126 / 127 - o próprio Docker não conseguiu rodar o contêiner. 125 significa que o daemon rejeitou o run (opções ruins, imagem faltando). 126, que o entrypoint existe mas não é executável. 127, que o caminho do entrypoint está errado ou falta o shell que ele precisa.
  • 1 ou 2 - o processo do Hermes Agent chegou a subir, passou pela validação dele e saiu com erro de aplicação. Rode docker logs hermes-agent --tail 100 e procure a primeira linha que não seja do banner de startup.

Só depois de saber em qual desses você está faz sentido mexer na configuração. Subir memória no chute ou reescrever o compose costuma esconder a causa real e produzir um contêiner que cai de novo uma semana depois pelo mesmo motivo.

Terminal mostrando a saída do docker inspect com o exit code, o flag OOMKilled e o campo error destacados

Passo 2 - Saída 137 com OOMKilled=true: a armadilha do VPS de 1 GB

De longe a causa mais comum no Hermes Agent, e a que o guia de VPS barato para IA já avisa. O agente parado não pesa, mas assim que você manda uma conversa longa, uma mensagem de voz ou uma chamada de ferramenta MCP, a memória sobe rápido. Num VPS de 1 GB sem swap, o OOM killer do kernel escolhe o maior processo (o gateway) e termina. A política de restart do Docker sobe outro contêiner na hora, que aloca memória do mesmo jeito e morre igual. Esse é o seu loop.

Confirme no log do kernel:

sudo dmesg -T | grep -i -E 'oom-kill|killed process' | tail -5
# ou em hosts com systemd:
sudo journalctl -k --since '30 minutes ago' | grep -i oom

Você vai ver uma linha nomeando o processo principal do contêiner (hermes ou node) e o RSS dele na hora do kill. Duas correções, em ordem de preferência:

  1. Dê mais RAM ao host. Abaixo de 2 GB, o Hermes Agent vai bater nesse teto toda vez que uma conversa esticar ou o modo voz entrar. O piso realista para um agente confortável de um usuário é 2 GB com swap ativa, ou 4 GB sem swap.
  2. Adicione swap no host. Num VPS Linux: sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile, e persista em /etc/fstab. Swap é mais lento que RAM, mas é a diferença entre um contêiner morto e uma resposta lenta.

Se você definiu um mem_limit explícito no compose, confira também. Um limite abaixo de 1 GB reproduz o mesmo OOM até num host grande. Tire o limite ou suba pelo menos para 1,5 GB antes de reiniciar.

Passo 3 - Saída 1 ou 2 com erro de config nos logs

Se o exit code é 1 ou 2, o Hermes Agent subiu o suficiente para rodar a validação dele e recusou a configuração. Os logs mostram o que falhou. Três formas cobrem quase todos os casos:

  • .env faltando ou mal formado. O gateway não sobe sem uma chave de provider válida. Procure Provider key not set ou Missing TELEGRAM_BOT_TOKEN nos logs. Confira se o .env não tem aspas soltas em volta dos valores (OPENROUTER_API_KEY="sk-..." está ok, OPENROUTER_API_KEY = "sk-..." com espaços não) nem quebras de linha do Windows (file .env deveria dizer ASCII text, não CRLF).
  • Diretório de dados sem permissão de escrita. Se aparecer EACCES: permission denied, open '/data/config.json', o contêiner roda como usuário não-root e o diretório bind-mount do host pertence a outra pessoa. No host: sudo chown -R 1000:1000 ~/.hermes/data. UID 1000 é o que a imagem usa; não rode o contêiner como root só para contornar isso.
  • Porta já ocupada. bind: address already in use significa que outro processo do host já está na porta 8642. Ache com sudo lsof -i :8642 e pare o outro processo, ou mapeie o Hermes Agent para outra porta no compose (ports: - "9642:8642").

Nenhum desses se resolve sozinho com restarts. Corrija a configuração e rode docker compose up -d de novo.

Passo 4 - Saída 139 ou "exec format error": a armadilha da imagem ARM

Se o contêiner morre em milissegundos com código 139, ou o Docker registra exec /usr/bin/node: exec format error, a imagem que você baixou não bate com a CPU do host. Costuma acontecer em Oracle Cloud Ampere, AWS Graviton ou Raspberry Pi, todos ARM64. Se você baixou uma imagem construída só para linux/amd64, o kernel não consegue executar o binário e o Docker fica tentando.

Confira as arquiteturas do host e da imagem:

uname -m                                   # aarch64 = ARM64, x86_64 = amd64
docker inspect hermes-agent-image \
  --format='{{.Architecture}}/{{.Os}}'     # deveria bater com uname -m

Se não bater, baixe indicando a plataforma. A imagem oficial do Hermes Agent é multi-arch, então basta especificar:

docker pull --platform linux/arm64 hermes/agent:latest

Se você constrói uma imagem própria, reconstrua com docker buildx build --platform linux/arm64,linux/amd64 e publique os dois tags. Rodar uma imagem ARM num host amd64 é o mesmo bug espelhado e produz o mesmo 139.

Passo 5 - A política de restart está escondendo o erro real

restart: always é o padrão certo para um agente em produção, mas durante o debug ele transforma toda falha de startup num loop apertado que enche os logs e esconde o primeiro erro real. Quando algo dá errado, mude para uma política que exponha a falha:

services:
  hermes-agent:
    image: hermes/agent:latest
    restart: "on-failure:3"

on-failure:3 reinicia até 3 vezes em saídas não zero e depois desiste. O contêiner para com a falha visível em docker ps -a, e os logs não são sobrescritos por novos boots. Assim que o problema for corrigido, volte para restart: always ou unless-stopped. O guia de debugging e observabilidade do Hermes Agent cobre a rotação de logs que mantém isso legível em produção.

Trecho de docker-compose.yml com a política de restart destacada, junto de uma saída de docker ps mostrando o contêiner parado

Quando não vale o fim de semana

Todas as falhas acima têm conserto, mas cada uma custa uma tarde de domingo lendo log de kernel e reescrevendo compose. Se você chegou até aqui porque o bot está fora do ar há três dias e só quer voltar a usar o agente, a versão gerenciada existe exatamente para isso. A Hermify roda o Hermes Agent para você no Telegram, com volume de memória, chaves de provider e política de restart já configurados, então o contêiner caindo deixa de ser seu problema. Comece com a Hermify e volte a ficar no ar em cerca de um minuto.

Para quem prefere continuar self-hosting, o próximo post é Hermes Agent memória e skills - o segundo motivo mais comum de um agente dockerizado parecer quebrado.

Sources

Lance seu próprio agente Hermes

Traga sua chave de API, conecte o Telegram e tenha um agente de IA que evolui sozinho no ar em 60 segundos.

Começar agora