Hermes Agent bajo Docker: instalación y blindaje probados

El «Hermes Agent» comparado con OpenClaw en 2026 es el de Nous Research: instalado y blindado bajo Docker en un laboratorio aislado, sin clave ni credencial introducida, con dos ajustes de red no documentados que hay que conocer antes de exponerlo.

Hermes Agent bajo Docker: instalación y blindaje probados
Respuesta rápida

El «Hermes Agent» comparado con OpenClaw en las búsquedas en español es el de Nous Research (NousResearch/hermes-agent, licencia MIT), no el cliente web hermes-webui ni el índice comunitario «HermesHub». Instalado y blindado bajo Docker en un laboratorio aislado, sin clave ni credencial introducida, arranca en 17 a 19 segundos hasta un punto de salud realmente positivo. Dos ajustes no documentados que hay que conocer antes de exponerlo: internal: true corta también el puerto publicado, no solo la salida a Internet, y la pasarela solo escucha por defecto en su propio bucle local, incluso detrás de un puerto ya restringido a 127.0.0.1 en el host.

«Hermes agent» y «hermes vs openclaw» aparecen regularmente en las búsquedas en español, pero el nombre es ambiguo: varios proyectos se llaman Hermes. Solo uno se compara con OpenClaw en las fuentes fechadas de 2026. Se identifica aquí, se instala y se blinda bajo Docker en un laboratorio aislado, distinguiendo en cada paso lo que realmente se ejecutó de lo que sigue solo documentado.

¿Qué Hermes Agent, exactamente?

El proyecto al que apuntan estas búsquedas es Hermes Agent, desarrollado por Nous Research y publicado bajo licencia MIT en el repositorio NousResearch/hermes-agent, . El repositorio mostraba 242.851 estrellas y 49.953 forks el 7 de septiembre de 2026, para una creación el 22 de julio de 2025. Su descripción cabe en una frase: «the agent that grows with you». Un agente único, que crea y afina sus propias competencias a partir de la experiencia, todo lo contrario de una plataforma de orquestación de varios agentes. Esa oposición de filosofía aparece en los comparativos publicados en 2026 frente a OpenClaw, y confirma que se trata del proyecto correcto para las búsquedas «hermes vs openclaw».

Dos trampas de nomenclatura que evitar. hermes-webui es un cliente web de terceros no mantenido por Nous Research. «HermesHub» designa un índice comunitario de competencias, distinto del hub oficial integrado en el CLI. Los dos se confunden fácilmente con el proyecto principal en los resultados de búsqueda. Hermes Agent se suma además a la lista que nuestro panorama de los agentes de código en línea de comandos compara entre sí.

Instalar Hermes Agent con Docker

La imagen oficial es nousresearch/hermes-agent. La documentación Docker describe un asistente de configuración interactivo y luego un lanzamiento como servicio:

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

El laboratorio de más abajo no retoma ese asistente interactivo: pasa directamente por un compose blindado que reproduce gateway run en una red y unos puertos distintos. El puerto 8642 sirve a la vez de punto de salud y de pasarela compatible con la API de OpenAI, el puerto 9119, opcional, sirve para el panel web. El volumen montado en /opt/data contiene .env, config.yaml, SOUL.md, así como las carpetas sessions/, memories/ y skills/. La documentación recomienda de 1 a 4 GB de memoria y de 1 a 2 núcleos según el uso.

Fijé la última versión fechada en vez de latest. Las releases de GitHub indican la v0.21.0 (tag v2026.8.31, «The Pantheon Release»), publicada el 31 de agosto de 2026, unos 5.800 commits y 760 colaboradores después de la versión anterior. La descarga tardó 1 min 47 s en esta máquina para 908 MB comprimidos (3,93 GB una vez descomprimidos, arquitectura arm64). La imagen v2026.4.30, 8,2 GB, sitúa un verdadero cambio de arquitectura interna entre abril y mayo de 2026. Ese punto de control todavía arranca con tini, mientras que la versión de agosto usa s6-overlay como PID 1, con abandono de privilegios hacia un usuario hermes (UID 10000 por defecto). Curiosidad observada de paso: el registro de Docker Hub muestra que el peso de la imagen pasó de unos 2,5 GB en abril a menos de 900 MB desde julio de 2026.

Blindar la configuración: red, puertos, secretos

El docker-compose.yml oficial declara network_mode: host tanto para la pasarela como para el panel, práctico, pero sin ninguna aislación de red. Para el laboratorio, construí una versión blindada: red dedicada, puertos publicados solo en el bucle local, secretos fuera del archivo 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     # clave de proveedor eventual, fuera del repositorio
    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 más abajo: sin esta línea, /health
    deploy:                       #   sigue inalcanzable aunque el puerto esté publicado
      resources:
        limits:
          memory: 1g
          cpus: "1.0"
    command: ["gateway", "run"]

networks:
  hermes_lab:
    driver: bridge

Dos ajustes del compose oficial se comportan de forma distinta a lo que deja esperar la documentación. El primero tiene que ver con la red. Marcar internal: true para cortar toda salida a Internet corta también el puerto publicado. En el laboratorio, una petición lanzada desde dentro del contenedor obtiene un HTTP 200 en /health. La misma petición desde la máquina host, sobre el puerto publicado, no recibe ninguna respuesta. Un intento de salida hacia example.com falla en una resolución DNS imposible. El aislamiento se sostiene, pues, pero se lleva por delante el uso local legítimo del puerto. internal: true solo conviene a un laboratorio totalmente fuera de línea. Para un uso real con un proveedor de modelo remoto, el aislamiento pasa por una red dedicada clásica y un cortafuegos de salida, no por este ajuste.

El segundo sorprende más. Incluso en la red dedicada sin marcar como internal, el puerto publicado seguía siendo inalcanzable, conexión TCP aceptada, respuesta HTTP vacía. Una búsqueda en el código instalado da la explicación exacta:

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 defecto, la pasarela solo escucha en el bucle local dentro del contenedor, independientemente de la red Docker elegida. De ahí la línea API_SERVER_HOST=0.0.0.0 en el compose de arriba: no cambia nada a la exposición externa, ya que es el prefijo 127.0.0.1: del puerto publicado el que ya la restringe. Comprobado tras la corrección: curl http://127.0.0.1:8642/health responde 200 desde el host, la misma petición enviada a la dirección de red local de la máquina (192.168.x.x) no recibe ninguna respuesta. En cuanto al panel, se niega directamente a arrancar en una interfaz no local sin proveedor de autenticación 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.

Comportamiento sano por defecto, con un efecto colateral visible en los registros. Dejado tal cual, sin autenticación configurada, el servicio no se queda simplemente desactivado, falla y luego se reinicia en bucle bajo la supervisión s6. Nada grave, pero lo bastante ruidoso como para merecer saberlo. Último punto comprobado: el límite deploy.resources.limits del compose de arriba sí se aplica fuera del modo Swarm con Docker Compose v5.1.0. docker inspect confirma Memory=1073741824 y NanoCpus=1000000000 en el contenedor lanzado. Versiones antiguas de Compose ignoraban deploy: fuera de Swarm.

Lo que se observa al arrancar

Una vez corregida la configuración, docker compose up -d y luego un sondeo de /health cada 0,3 segundos dan un tiempo de arranque de unos 18,9 segundos en frío (carpeta de datos vacía) y 16,6 segundos tras un simple reinicio. La diferencia se debe sobre todo a una fase de precalentamiento interno, que los registros nombran explícitamente «turn-machinery warm-up» y que abre la puerta de entrada a los 20 segundos aunque continúe en segundo plano. Por dentro, ps aux confirma que el supervisor sigue siendo root pero que el proceso hermes gateway run sí corre bajo el usuario sin privilegios hermes. El banner de arranque muestra Hermes Agent v0.21.0 (2026.8.31), Python 3.13.5 y el SDK de OpenAI 2.24.0.

Puerto o archivo Función Acceso por defecto
8642 Salud + pasarela compatible con la API de OpenAI Bucle local del contenedor (API_SERVER_HOST=127.0.0.1)
9119 Panel web Rechaza toda vinculación no local sin autenticación
/opt/data/.env Claves de proveedores de modelos y herramientas Modelo totalmente comentado, ninguna clave activa en la instalación
/opt/data/config.yaml Modelo por defecto, terminal, compresión de contexto Generado en el primer arranque

Conectarse a un modelo

El archivo .env generado en el primer arranque lista, enteramente en comentarios, una treintena de proveedores (Fireworks, OpenRouter, NovitaAI, Gemini, z.ai, Kimi, MiniMax, OpenCode Zen…) y otras tantas claves de herramientas (Firecrawl, Exa, Browserbase), ninguna está activa. «Ollama» solo aparece ahí en forma de OLLAMA_API_KEY, el servicio en la nube de pago de Ollama, y ninguna entrada apunta a una instancia local. El diagnóstico integrado confirma el estado neutro de la instalación:

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 en .env al final de la prueba: una API_SERVER_KEY generada automáticamente por el contenedor, para proteger su propia pasarela local. Nunca aparece en claro en los registros, nadie la introdujo, y no guarda relación con una cuenta en un proveedor de modelos.

Las competencias, y cómo verificar una antes de instalarla

Las competencias («skills») viven en /opt/data/skills/ y siguen el estándar abierto Agent Skills detallado en nuestra guía del SKILL.md. hermes skills list contaba 53 competencias integradas activadas en este laboratorio, ninguna instalada desde el hub. La instalación se hace por registro: hermes skills install official/security/1password o hermes skills install openai/skills/k8s, por ejemplo. Antes de instalar nada, dos comandos evitan tener que confiar a ciegas:

bash
hermes skills inspect openai/skills/k8s   # metadatos, repositorio de origen, auditoría ya disponible
hermes skills audit                       # vuelve a escanear todas las skills instaladas desde el hub

El escáner integrado clasifica cada resultado en tres niveles: dangerous bloquea la instalación, warn/caution se salta con --force, advisory queda solo informativo. Según la documentación oficial, el hub agregaba 90.700 competencias repartidas en 11 registros a fecha del 26 de agosto de 2026, que no hay que confundir con «HermesHub», el índice comunitario de terceros mencionado más arriba.

MCP: conectar herramientas, o exponer Hermes como servidor

hermes mcp catalog, ejecutado en el laboratorio, muestra un catálogo ya largo de servidores listos para usar (Airtable, Atlassian, Cloudflare, ClickUp, Buildkite…). hermes mcp list confirmaba que ninguno estaba configurado, como cabía esperar en una instalación nueva. La adición se hace con un preajuste conocido o una entrada manual:

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

En el otro sentido, hermes mcp serve expone una sesión Hermes como servidor MCP a un cliente externo, Claude Code, por ejemplo, apuntando su configuración hacia el comando hermes mcp serve. En cuanto a seguridad, la documentación precisa tres cosas. Los tokens OAuth remotos se cachean con permisos 0600. La renovación pasa por PKCE. Para los servidores en stdio, solo las variables de entorno explícitamente declaradas, más una base mínima, se transmiten al subproceso. Suficiente para limitar las fugas de secretos hacia un servidor MCP de terceros mal auditado, un riesgo ya documentado en nuestro artículo sobre agentes de código, sandbox y permisos.

Hermes Agent contra OpenClaw: una comparación honesta

Los dos proyectos son de código abierto, se instalan bajo Docker y soportan skills y MCP, es su filosofía la que diverge. OpenClaw estructura una pasarela que enruta y vigila varios agentes, conectores y canales. Hermes Agent apuesta por un agente único que acumula sus propias competencias con el uso. Nuestro artículo sobre la instalación blindada de OpenClaw detalla el mismo ejercicio del lado de OpenClaw, los dos se leen en espejo.

En cuanto a seguridad, una nota de investigación de la Cloud Security Alliance fechada el 4 de mayo de 2026 recoge, en el mismo periodo, nueve CVE para OpenClaw, de las cuales una crítica puntuada 9,9, frente a dos para el núcleo de Hermes Agent. CVE-2026-7396 se refiere a un recorrido de ruta en el adaptador WeCom (CVSS 4,0), CVE-2026-7397 a un seguimiento de enlace simbólico en las herramientas de archivos (CVSS 4,8), ambas en la versión 0.8.0 y corregidas ya en la 0.9.0. Una tercera CVE listada afecta no al agente sino a hermes-webui, el cliente de terceros ya señalado más arriba. La página GitHub Security Advisories del repositorio no recoge, por su parte, ningún aviso publicado a 7 de septiembre de 2026: esas CVE se depositaron por canales externos, no por la propia Nous Research. Hasta hoy no se ha publicado ningún recuento de instancias Hermes expuestas comparable a la cifra verificada para OpenClaw (42.900 instancias, 93 % sin autenticación, SecurityScorecard 2026), lo que no prueba su ausencia.

Un incidente fechado ilustra por qué el aislamiento de red y la ausencia de modo automático importan tanto como la elección del proyecto. The Hacker News documentó, el 24 de julio de 2026, un caso en el que un atacante que ya disponía de un acceso inicial a la red del ministerio de Finanzas tailandés instaló Hermes Agent en un servidor alquilado y activó después su modo «YOLO», que se salta las confirmaciones antes de los comandos arriesgados. El agente exploró luego la red sin supervisión, encontró servicios Hadoop con credenciales por defecto y desplegó un implante. Punto subrayado por la propia fuente: Hermes no provocó la intrusión, automatizó la fase siguiente. La red dedicada, los puertos en bucle local y la ausencia de clave introducida en este laboratorio buscan impedir exactamente esa fase.

Lo que hay que recordar

  • El «Hermes Agent» comparado con OpenClaw en 2026 es el de Nous Research (NousResearch/hermes-agent, licencia MIT), no hermes-webui ni «HermesHub», dos proyectos de terceros con nombre parecido.
  • Última versión fechada probada: v0.21.0 (tag v2026.8.31, 31 de agosto de 2026), instalada vía Docker en 1 min 47 s (908 MB comprimidos, 3,93 GB descomprimidos).
  • Una red marcada como internal: true corta también el puerto publicado, no solo la salida a Internet. Por defecto, la pasarela solo escucha en su propio bucle local (API_SERVER_HOST=127.0.0.1), hay que corregirlo explícitamente incluso detrás de un puerto ya restringido a 127.0.0.1 en el host.
  • El panel se niega a exponerse fuera del bucle local sin autenticación configurada. Sano por defecto, pero dejado así entra en bucle de fallo en vez de quedarse simplemente inactivo.
  • Arranque medido en unos 17 a 19 segundos hasta un /health realmente positivo, sin ninguna clave ni credencial introducida de principio a fin.
  • En el mismo periodo, la Cloud Security Alliance recoge dos CVE menores para el núcleo de Hermes Agent frente a nueve para OpenClaw, de las cuales una crítica. La diferencia se lee con prudencia: no se ha publicado ningún recuento de exposición equivalente para Hermes.

Errores frecuentes

internal: true también bloquea el puerto publicado Marcar la red como interna corta la salida del contenedor, pero también el puerto publicado por ports:, probado aquí: docker exec obtiene un 200, la misma llamada desde el host no recibe ninguna respuesta.
La pasarela solo escucha en 127.0.0.1 por defecto Dentro del contenedor, no solo del lado del host: sin API_SERVER_HOST=0.0.0.0, el puerto publicado se conecta pero devuelve una respuesta HTTP vacía, incluso fuera de la red internal.
El compose oficial usa network_mode: host Ninguna aislación de red por defecto, la red dedicada y los puertos en 127.0.0.1 de este artículo se apartan de eso a propósito.
El panel entra en bucle de fallo sin autenticación Dejar HERMES_DASHBOARD=1 sin proveedor de autenticación no lo desactiva en silencio: falla y se reinicia en bucle bajo s6.
hermes doctor reclama una migración incluso en una instalación nueva El mensaje habla de una configuración «~2 years old» aunque el contenedor se acaba de crear, un modelo incorporado en la imagen, sin consecuencia bloqueante.

DockerHermes AgentMCPSécuritéSkills

Damien Flandrin Desarrollador web desde 2010, creador de Gekkode y de Email Impact. Cada artículo se prueba en un proyecto real antes de publicarse. Contacto
Newsletter

Las nuevas pruebas, tutoriales y proyectos, por correo.

Pruebas reproducibles, código versionado, resultados fechados. Nunca spam.