Hermes Agent com Docker: instalação e blindagem testadas

O «Hermes Agent» comparado ao OpenClaw em 2026 é o da Nous Research: instalado e blindado sob Docker num laboratório isolado, sem chave nem credencial introduzida, com duas definições de rede não documentadas a conhecer antes de o expor.

Hermes Agent com Docker: instalação e blindagem testadas
Resposta rápida

O «Hermes Agent» comparado ao OpenClaw nas pesquisas em português é o da Nous Research (NousResearch/hermes-agent, licença MIT), não o cliente web hermes-webui nem o índice comunitário «HermesHub». Instalado e blindado sob Docker num laboratório isolado, sem chave nem credencial introduzida, arranca em 17 a 19 segundos até um ponto de saúde realmente positivo. Duas definições não documentadas a conhecer antes de o expor: internal: true corta também a porta publicada, não só a saída para a Internet, e a gateway só escuta por defeito na sua própria loopback local, mesmo atrás de uma porta já restrita a 127.0.0.1 do lado do anfitrião.

«Hermes agent» e «hermes vs openclaw» voltam regularmente nas pesquisas em português, mas o nome é ambíguo: vários projetos se chamam Hermes. Só um é comparado ao OpenClaw nas fontes datadas de 2026. É identificado aqui, instalado e blindado sob Docker num laboratório isolado, distinguindo em cada etapa o que realmente correu do que fica apenas documentado.

Que Hermes Agent, exatamente?

O projeto visado por estas pesquisas é o Hermes Agent, desenvolvido pela Nous Research e publicado sob licença MIT no repositório NousResearch/hermes-agent, . O repositório exibia 242 851 estrelas e 49 953 forks a 7 de setembro de 2026, para uma criação a 22 de julho de 2025. A sua descrição cabe numa frase: «the agent that grows with you». Um agente único, que cria e afina as suas próprias competências a partir da experiência, ao contrário de uma plataforma de orquestração de vários agentes. Esta oposição de filosofia aparece nos comparativos publicados em 2026 face ao OpenClaw, e confirma tratar-se mesmo do projeto por detrás das pesquisas «hermes vs openclaw».

Duas armadilhas de nomenclatura a evitar. hermes-webui é um cliente web de terceiros não mantido pela Nous Research. «HermesHub» designa um índice comunitário de competências, distinto do hub oficial integrado no CLI. Os dois confundem-se facilmente com o projeto principal nos resultados de pesquisa. O Hermes Agent junta-se aliás à lista que o nosso panorama dos agentes de código em linha de comandos compara entre si.

Instalar o Hermes Agent com Docker

A imagem oficial é nousresearch/hermes-agent. A documentação Docker descreve um assistente de configuração interativo e depois um arranque como serviço:

bash
mkdir -p ~/.hermes
docker run -it --rm -v ~/.hermes:/opt/data nousresearch/hermes-agent setup

docker run -d --name hermes --restart unless-stopped \
  -v ~/.hermes:/opt/data -p 8642:8642 \
  nousresearch/hermes-agent gateway run

O laboratório mais abaixo não retoma esse assistente interativo: passa diretamente por um compose blindado que reproduz o gateway run numa rede e em portas diferentes. A porta 8642 serve ao mesmo tempo de ponto de saúde e de gateway compatível com a API OpenAI, a porta 9119, opcional, serve para o painel web. O volume montado em /opt/data contém .env, config.yaml, SOUL.md, bem como as pastas sessions/, memories/ e skills/. A documentação recomenda 1 a 4 GB de memória e 1 a 2 núcleos consoante o uso.

Fixei a última versão datada em vez de latest. As releases do GitHub indicam a v0.21.0 (tag v2026.8.31, «The Pantheon Release»), publicada a 31 de agosto de 2026, cerca de 5 800 commits e 760 contribuidores depois da versão anterior. O download demorou 1 min 47 s nesta máquina para 908 MB comprimidos (3,93 GB depois de descomprimidos, arquitetura arm64). A imagem v2026.4.30, 8,2 GB, situa uma verdadeira mudança de arquitetura interna entre abril e maio de 2026. Este ponto de controlo ainda arranca com tini, enquanto a versão de agosto usa s6-overlay como PID 1, com abandono de privilégios para um utilizador hermes (UID 10000 por defeito). Curiosidade notada de passagem: o registo Docker Hub mostra que o peso da imagem passou de cerca de 2,5 GB em abril para menos de 900 MB desde julho de 2026.

Blindar a configuração: rede, portas, segredos

O docker-compose.yml oficial declara network_mode: host tanto para a gateway como para o painel, prático, mas sem nenhuma isolação de rede. Para o laboratório, construí uma versão blindada: rede dedicada, portas publicadas só na loopback local, segredos fora do ficheiro compose.

yaml
services:
  hermes:
    image: nousresearch/hermes-agent:v2026.8.31
    container_name: hermes-lab
    networks:
      - hermes_lab
    ports:
      - "127.0.0.1:8642:8642"
      - "127.0.0.1:9119:9119"
    volumes:
      - ./data:/opt/data
    env_file:
      - ./secrets/hermes.env     # eventual chave de fornecedor, fora do repositório
    environment:
      - HERMES_UID=501
      - HERMES_GID=20
      - HERMES_DASHBOARD=1
      - HERMES_DASHBOARD_HOST=0.0.0.0
      - API_SERVER_HOST=0.0.0.0   # ver mais abaixo: sem esta linha, /health
    deploy:                       #   continua incontactável mesmo com a porta publicada
      resources:
        limits:
          memory: 1g
          cpus: "1.0"
    command: ["gateway", "run"]

networks:
  hermes_lab:
    driver: bridge

Duas definições do compose oficial comportam-se de forma diferente do que a documentação deixa esperar. A primeira tem a ver com a rede. Marcá-la como internal: true para cortar toda a saída para a Internet corta também a porta publicada. No laboratório, um pedido lançado de dentro do contentor obtém um HTTP 200 em /health. O mesmo pedido a partir da máquina anfitriã, na porta publicada, não recebe nenhuma resposta. Uma tentativa de saída para example.com falha numa resolução DNS impossível. A isolação aguenta, portanto, mas leva consigo o uso local legítimo da porta. internal: true só serve para um laboratório inteiramente offline. Para um uso real com um fornecedor de modelo remoto, a isolação passa por uma rede dedicada clássica e uma firewall de saída, não por esta definição.

A segunda surpreende mais. Mesmo na rede dedicada não marcada como internal, a porta publicada continuava incontactável, ligação TCP aceite, resposta HTTP vazia. Uma pesquisa no código instalado dá a explicação exata:

bash
docker exec hermes-lab grep -r API_SERVER_HOST /opt/hermes/hermes_cli/security_audit_startup.py

host = extra.get("host") or os.environ.get("API_SERVER_HOST", "127.0.0.1")

Por defeito, a gateway só escuta na loopback local dentro do contentor, independentemente da rede Docker escolhida. Daí a linha API_SERVER_HOST=0.0.0.0 no compose acima: não muda nada à exposição externa, já que é o prefixo 127.0.0.1: da porta publicada que já a restringe. Verificado depois da correção: curl http://127.0.0.1:8642/health responde 200 a partir do anfitrião, o mesmo pedido enviado para o endereço de rede local da máquina (192.168.x.x) não recebe nenhuma resposta. Quanto ao painel, este recusa-se pura e simplesmente a arrancar numa interface não local sem fornecedor de autenticação configurado:

bash
Refusing to bind dashboard to 0.0.0.0 — the auth gate engages on non-loopback
binds (0.0.0.0), but no auth providers are registered.
There is no unauthenticated public-dashboard option.

Comportamento saudável por defeito, com um efeito colateral visível nos registos. Deixado tal como está, sem autenticação configurada, o serviço não fica simplesmente desativado, falha e depois reinicia em ciclo sob a supervisão s6. Nada de grave, mas suficientemente ruidoso para valer a pena saber. Último ponto verificado: o limite deploy.resources.limits do compose acima aplica-se mesmo fora do modo Swarm com o Docker Compose v5.1.0. docker inspect confirma Memory=1073741824 e NanoCpus=1000000000 no contentor lançado. Versões antigas do Compose ignoravam deploy: fora do Swarm.

O que se observa no arranque

Depois de corrigida a configuração, um docker compose up -d seguido de uma sondagem a /health a cada 0,3 segundos dá um tempo de arranque de cerca de 18,9 segundos a frio (pasta de dados vazia) e 16,6 segundos depois de um simples reinício. A diferença deve-se sobretudo a uma fase de pré-aquecimento interno, que os registos nomeiam explicitamente «turn-machinery warm-up» e que abre a porta de entrada ao fim de 20 segundos mesmo que continue em segundo plano. Por dentro, ps aux confirma que o supervisor continua root mas que o processo hermes gateway run corre mesmo sob o utilizador sem privilégios hermes. O banner de arranque mostra Hermes Agent v0.21.0 (2026.8.31), Python 3.13.5 e o SDK OpenAI 2.24.0.

Porta ou ficheiro Papel Acesso por defeito
8642 Saúde + gateway compatível com a API OpenAI Loopback local do contentor (API_SERVER_HOST=127.0.0.1)
9119 Painel web Recusa qualquer ligação não local sem autenticação
/opt/data/.env Chaves de fornecedores de modelos e de ferramentas Modelo inteiramente comentado, nenhuma chave ativa na instalação
/opt/data/config.yaml Modelo por defeito, terminal, compressão de contexto Gerado no primeiro arranque

Ligar-se a um modelo

O ficheiro .env gerado no primeiro arranque lista, inteiramente em comentários, uns trinta fornecedores (Fireworks, OpenRouter, NovitaAI, Gemini, z.ai, Kimi, MiniMax, OpenCode Zen…) e outras tantas chaves de ferramentas (Firecrawl, Exa, Browserbase), nenhuma está ativa. «Ollama» só aparece aí sob a forma OLLAMA_API_KEY, o serviço cloud pago do Ollama, e nenhuma entrada visa uma instância local. O diagnóstico integrado confirma o estado neutro da instalação:

bash
docker exec hermes-lab hermes doctor

✓ No active security advisories
✓ No suspicious MCP stdio commands
✓ Version files consistent (0.21.0)
◆ API Connectivity
  ⚠ OpenRouter API (not configured)
◆ Memory Provider
  ✓ Built-in memory active (no external provider configured — this is fine)

Único valor presente em .env no final do teste: uma API_SERVER_KEY gerada automaticamente pelo contentor, para proteger a sua própria gateway local. Nunca aparece em claro nos registos, ninguém a introduziu, e não tem relação com uma conta junto de um fornecedor de modelo.

As competências, e como verificar uma antes de a instalar

As competências («skills») vivem em /opt/data/skills/ e seguem o standard aberto Agent Skills detalhado no nosso guia do SKILL.md. hermes skills list contava 53 competências integradas ativadas neste laboratório, nenhuma instalada a partir do hub. A instalação faz-se por registo: hermes skills install official/security/1password ou hermes skills install openai/skills/k8s, por exemplo. Antes de instalar seja o que for, dois comandos evitam ter de confiar às cegas:

bash
hermes skills inspect openai/skills/k8s   # metadados, repositório de origem, auditoria já disponível
hermes skills audit                       # reanalisa todos os skills instalados a partir do hub

O scanner integrado classifica cada resultado em três níveis: dangerous bloqueia a instalação, warn/caution contorna-se com --force, advisory fica só informativo. Segundo a documentação oficial, o hub agregava 90 700 competências repartidas por 11 registos a 26 de agosto de 2026, a não confundir com «HermesHub», o índice comunitário terceiro referido mais acima.

MCP: ligar ferramentas, ou expor o Hermes como servidor

hermes mcp catalog, executado no laboratório, mostra um catálogo já longo de servidores prontos a usar (Airtable, Atlassian, Cloudflare, ClickUp, Buildkite…). hermes mcp list confirmava que nenhum estava configurado, como esperado numa instalação nova. A adição faz-se com uma predefinição conhecida ou uma entrada manual:

bash
hermes mcp add codex --preset codex
hermes mcp add filesystem --command npx --args "-y @modelcontextprotocol/server-filesystem /projet"

No outro sentido, hermes mcp serve expõe uma sessão Hermes como servidor MCP a um cliente externo, o Claude Code, por exemplo, apontando a sua configuração para o comando hermes mcp serve. Do lado da segurança, a documentação precisa três coisas. Os tokens OAuth remotos são postos em cache com permissões 0600. A renovação passa por PKCE. Para os servidores em stdio, só as variáveis de ambiente explicitamente declaradas, mais uma base mínima, são transmitidas ao subprocesso. O suficiente para limitar as fugas de segredos para um servidor MCP de terceiros mal auditado, um risco já documentado no nosso artigo sobre agentes de código, sandbox e permissões.

Hermes Agent contra OpenClaw: uma comparação honesta

Os dois projetos são open source, instalam-se sob Docker e suportam skills e MCP, é a sua filosofia que diverge. O OpenClaw estrutura uma gateway que encaminha e vigia vários agentes, conectores e canais. O Hermes Agent aposta num agente único que acumula as suas próprias competências ao longo do uso. O nosso artigo sobre a instalação blindada do OpenClaw detalha o mesmo exercício do lado do OpenClaw, os dois leem-se em espelho.

Sobre a segurança, uma nota de investigação da Cloud Security Alliance datada de 4 de maio de 2026 recenseia, no mesmo período, nove CVE para o OpenClaw das quais uma crítica com nota 9,9, contra duas para o núcleo do Hermes Agent. A CVE-2026-7396 incide sobre uma travessia de caminho no adaptador WeCom (CVSS 4,0), a CVE-2026-7397 sobre um seguimento de link simbólico nas ferramentas de ficheiros (CVSS 4,8), ambas na versão 0.8.0 e corrigidas já na 0.9.0. Uma terceira CVE listada não afeta o agente mas sim o hermes-webui, o cliente terceiro já referido mais acima. A página GitHub Security Advisories do repositório, essa, não refere nenhum aviso publicado a 7 de setembro de 2026: estas CVE foram depositadas por canais externos, não pela própria Nous Research. Até hoje não foi publicado nenhum levantamento de instâncias Hermes expostas comparável ao número verificado para o OpenClaw (42 900 instâncias, 93% sem autenticação, SecurityScorecard 2026), o que não prova a sua ausência.

Um incidente datado ilustra porque é que o isolamento de rede e a ausência de modo automático contam tanto como a escolha do projeto. O The Hacker News documentou, a 24 de julho de 2026, um caso em que um atacante já com acesso inicial à rede do ministério das Finanças tailandês instalou o Hermes Agent num servidor alugado e ativou em seguida o seu modo «YOLO», que salta as confirmações antes dos comandos arriscados. O agente explorou depois a rede sem supervisão, encontrou serviços Hadoop com credenciais por defeito e implementou um implante. Ponto sublinhado pela própria fonte: o Hermes não provocou a intrusão, automatizou a fase seguinte. A rede dedicada, as portas na loopback local e a ausência de chave introduzida neste laboratório visam impedir exatamente essa fase.

A reter

  • O «Hermes Agent» comparado ao OpenClaw em 2026 é o da Nous Research (NousResearch/hermes-agent, licença MIT), não o hermes-webui nem o «HermesHub», dois projetos terceiros de nome parecido.
  • Última versão datada testada: v0.21.0 (tag v2026.8.31, 31 de agosto de 2026), instalada via Docker em 1 min 47 s (908 MB comprimidos, 3,93 GB descomprimidos).
  • Uma rede marcada como internal: true corta também a porta publicada, não só a saída para a Internet. Por defeito, a gateway só escuta na sua própria loopback local (API_SERVER_HOST=127.0.0.1), a corrigir explicitamente mesmo atrás de uma porta já restrita a 127.0.0.1 do lado do anfitrião.
  • O painel recusa-se a expor-se fora da loopback local sem autenticação configurada. Saudável por defeito, mas deixado assim entra em ciclo de falha em vez de ficar simplesmente inativo.
  • Arranque medido em cerca de 17 a 19 segundos até um /health realmente positivo, sem nenhuma chave nem credencial introduzida de ponta a ponta.
  • No mesmo período, a Cloud Security Alliance recenseia duas CVE menores para o núcleo do Hermes Agent contra nove para o OpenClaw, das quais uma crítica. O desfasamento lê-se com prudência: não foi publicado nenhum levantamento de exposição equivalente para o Hermes.

Erros frequentes

internal: true bloqueia também a porta publicada Marcar a rede como interna corta a saída do contentor, mas também a porta publicada por ports:, testado aqui: docker exec obtém um 200, a mesma chamada a partir do anfitrião não recebe nenhuma resposta.
A gateway só escuta em 127.0.0.1 por defeito Dentro do contentor, não só do lado do anfitrião: sem API_SERVER_HOST=0.0.0.0, a porta publicada liga-se mas devolve uma resposta HTTP vazia, mesmo fora de uma rede internal.
O compose oficial usa network_mode: host Nenhuma isolação de rede por defeito, a rede dedicada e as portas em 127.0.0.1 deste artigo afastam-se disso deliberadamente.
O painel entra em ciclo de falha sem autenticação Deixar HERMES_DASHBOARD=1 sem fornecedor de autenticação não o desativa silenciosamente: falha e reinicia em ciclo sob o s6.
hermes doctor reclama uma migração mesmo numa instalação nova A mensagem refere uma configuração «~2 years old» quando o contentor acabou de ser criado, um modelo embutido na imagem, sem consequência bloqueante.

DockerHermes AgentMCPSécuritéSkills

Damien Flandrin Programador web desde 2010, criador da Gekkode e do Email Impact. Cada artigo é testado num projeto real antes de ser publicado. Contacto
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.