SSD Nodes Learn Hosting plans →
Guías Matt ConnorPor Matt Connor

HarnessRouter: una API para Codex, Claude y Hermes

Aloje Codex, Claude Code y Hermes tras una API propia. Incluye Docker, enlace loopback, cambio del acceso predeterminado y acceso TLS seguro.

Qué elimina HarnessRouter

Autohospedas HarnessRouter Community Edition para poner una API delante de varios agent harnesses en un servidor que administras. Un agent harness es el programa de línea de comandos que ejecuta un modelo en un bucle: mantiene una sesión, edita archivos, ejecuta comandos y transmite el progreso a quien solicitó el trabajo. Codex, Claude Code y Hermes cumplen esa función, y cada uno tiene su propia instalación, su propio formato de credenciales y su propia idea de lo que es una sesión. HarnessRouter ejecuta todos dentro de un solo contenedor y pone delante un único endpoint HTTP, un único inicio de sesión y un único almacén de secretos.

Esa es toda la idea, y conviene explicar claramente el coste. Añades un contenedor, un inicio de sesión, un volumen y un procedimiento de actualización al servidor para convertir varios componentes en uno solo. Si actualmente ejecutas exactamente un harness, esta configuración es peor que instalar ese harness directamente. Ese intercambio se analiza en la última sección, así que léela antes de desplegarlo.

Todo lo que aparece a continuación se comprobó con la etiqueta de imagen 0.5.5, descargada el 19 de agosto de 2026. El proyecto publica etiquetas nuevas casi todos los días, así que comprueba la etiqueta que realmente ejecutas en lugar de confiar en esta página dentro de un mes. El 12 de octubre de 2026 se volvió a comprobar esta página con la documentación actual del proyecto. En ese momento, latest apuntaba a 0.32.9, y se indican los casos en que las versiones actuales se comportan de forma diferente. Los comandos proceden del repositorio del proyecto en github.com/HarnessRouter/harnessrouter. Estaban en el README en 0.5.5; los detalles de configuración ahora se encuentran en docs/self-hosting-guide.md, en el mismo repositorio.

Qué es realmente el Unified Harness Protocol

HarnessRouter implementa el Unified Harness Protocol (UHP), publicado en unifiedharnessprotocol.org. UHP describe cómo un producto inicia una tarea en un harness, la supervisa mientras se ejecuta, administra sesiones y archivos, e informa de los fallos. La especificación se versiona por fecha. La versión vigente el 19 August 2026 tenía fecha 2026-08-11. A fecha de 12 October 2026, el sitio indica que 2026-10-04 es la versión actual y todavía la describe como un estándar preliminar, «lo bastante estable para basarse en él y versionado para poder cambiar de forma segura».

Lea con atención la expresión «estándar abierto». La misma empresa redacta la especificación, mantiene la implementación de referencia y desarrolla la suite de conformidad que determina quién cumple. Además, las reglas de gobierno del proyecto establecen que ningún cambio se incorpora si las tres partes no se actualizan juntas. A fecha de 12 October 2026, el sitio del protocolo describe esa suite como un conjunto de 95 comprobaciones ejecutables, mientras que la ejecución de referencia registrada en la guía de self-hosting, con fecha 4 September 2026, superó 64. Por tanto, el recuento todavía cambia. Esto es normal en un protocolo tan reciente, y la licencia Apache-2.0 permite bifurcar cualquier parte. También significa que UHP todavía no es un estándar de varios proveedores. Trátelo como un protocolo emergente: útil, sujeto a cambios y diseñado para que su propio código pueda dejar de usarlo sin reescrituras.

Lo que necesita antes de empezar

Docker y aproximadamente 4 GB de espacio libre en disco. También necesita una clave de API de un proveedor de modelos por el que ya pague. La descarga de la imagen ocupa unos 700 MB. El resto del espacio se utiliza para las CLI de los agentes y los espacios de trabajo en los que escriben. La imagen no incluye ningún modelo ni ninguna clave de prueba. Por tanto, las tareas fallan hasta que conecte un proveedor. HarnessRouter utiliza la licencia Apache-2.0. Las CLI de los agentes no están cubiertas por esa licencia. Por este motivo, se descargan durante el primer arranque en lugar de incluirse en la imagen.

Alojar HarnessRouter con docker run

docker pull harnessrouter/harnessrouter
docker run -d --name harnessrouter \
  -p 127.0.0.1:3000:3000 \
  -v harnessrouter:/data \
  harnessrouter/harnessrouter

A continuación, supervise el arranque del contenedor. El primer inicio es lento y los registros indican la causa.

docker logs -f harnessrouter

Mientras funciona, verá líneas como estas:

installing Claude Code (Anthropic's terms apply)…
installing Codex (Apache-2.0)…
installing Hermes (check its upstream license before use)…

Espere a ready on :3000. La guía actual indica que la consola necesita aproximadamente otro medio minuto después de esa línea antes de que http://localhost:3000 responda. Las CLI instaladas se almacenan en la caché del volumen, por lo que los inicios posteriores suelen ser mucho más rápidos. Sin embargo, un backend que añada más adelante, o cuya instalación haya fallado antes, todavía puede iniciar tareas de instalación.

De esa descarga se derivan dos hechos importantes en un VPS. Primero, el primer arranque necesita acceso de salida a la red. La imagen no es autosuficiente. Por tanto, un servidor detrás de un filtro de salida, o sin una ruta al exterior, no puede descargar las CLI de los agentes. En el 0.5.5 probado aquí, esto se manifestó como un primer inicio que nunca mostró ready on :3000. Es un momento confuso para descubrirlo, porque docker pull ya había funcionado. Las versiones actuales tratan una instalación fallida como un error no crítico y la indican en el registro. Por tanto, compruebe qué backends omite la línea backends available:. Segundo, está instalando software de terceros sujeto a condiciones de terceros. Claude Code se distribuye conforme a las condiciones de Anthropic y Hermes conforme a las condiciones que indique su proyecto original. Revise ambas antes de usar este software con fines comerciales.

-v harnessrouter:/data crea un volumen de Docker con nombre. Todos los datos persistentes se almacenan en /data: las bases de datos SQLite, los archivos almacenados, el almacén de secretos y los espacios de trabajo de los agentes. Si elimina ese volumen, elimina la instancia, incluidas las claves de los proveedores y todas las transcripciones. Haga la copia de seguridad con el contenedor detenido. Copiar una base de datos SQLite mientras se está escribiendo produce un archivo que podría no abrirse. La misma disciplina de detener y después copiar se aplica a todos los contenedores con estado del servidor, aunque los detalles varían según el servicio, ya que PhotoPrism e Immich necesitan sus propios comandos de copia de seguridad.

docker stop harnessrouter
docker run --rm -v harnessrouter:/data -v "$PWD":/backup alpine \
  tar czf /backup/harnessrouter-data.tgz -C / data
docker start harnessrouter

La variante de Compose y la línea que debe cambiar

El repositorio incluye un archivo de Compose. Publica "3000:3000", lo que significa que escucha en todas las interfaces del host. Cambie esa línea antes de iniciarlo en un servidor público.

services:
  harnessrouter:
    image: harnessrouter/harnessrouter:0.5.5
    ports:
      - "127.0.0.1:3000:3000"
    env_file:
      - .env
    volumes:
      - harnessrouter-data:/data
    restart: unless-stopped

volumes:
  harnessrouter-data:

Hay dos diferencias respecto al repositorio original: la dirección de enlace y una etiqueta de versión fijada en lugar de latest. Fijar la versión es importante porque se publicaron dieciséis etiquetas de versión entre el 9 y el 18 de agosto de 2026, y el ritmo no ha disminuido: el 12 de octubre de 2026 se publicaron cinco etiquetas preliminares 0.33.0 en Docker Hub. Un runtime de agente que cambia sin control es difícil de depurar. Fije la versión actual en lugar de copiar 0.5.5 de esta página; el 12 de octubre de 2026 era 0.32.9. Después, copie el archivo de entorno, restrinja sus permisos e inícielo.

cp .env.example .env
chmod 600 .env
docker compose up -d
docker compose logs -f

.env contiene la clave del proveedor en texto plano, por lo que el modo 600 es el mínimo. Si el subcomando docker compose no le resulta familiar, la hoja de referencia de comandos de Docker Compose cubre las operaciones habituales.

Por qué el puerto se publica en 127.0.0.1 y no en 0.0.0.0

-p 3000:3000 publica el puerto en todas las interfaces del host. -p 127.0.0.1:3000:3000 lo publica sólo en la interfaz de loopback, por lo que la única forma de acceder es desde el propio VPS. El contenedor siempre escucha en el puerto 3000 internamente, así que debes cambiar el valor de la izquierda. Comprueba el resultado:

docker port harnessrouter
sudo ss -ltnp | grep 3000

ss mostrando 127.0.0.1:3000 es correcto. 0.0.0.0:3000 significa que la consola está expuesta en Internet. En este caso, eso es más grave que con la mayoría de las aplicaciones autohospedadas, porque la consola crea harnesses, lee todas las transcripciones, ejecuta agentes y proporciona a esos agentes un shell y un sistema de archivos real en su espacio de trabajo. También contiene la clave del proveedor que configuraste. Cualquiera que acceda a una consola sin protección puede leer tu trabajo, ejecutar comandos y consumir tu clave.

Un firewall del host no evita este problema. Docker publica los puertos escribiendo sus propias reglas en la tabla nat del kernel, y esas reglas se evalúan antes de la cadena que gestiona ufw. Por eso, un puerto publicado sigue siendo accesible aunque sudo ufw status lo muestre como denegado. Haz la prueba desde otra máquina, no desde el VPS; de lo contrario, no comprobarás nada. Esta es la misma lección que ejecutar dsh sin interfaz en el puerto 3080: vincula el servicio a loopback y decide de forma deliberada cómo acceder a él.

Cambie el inicio de sesión predeterminado antes de hacer cualquier otra cosa

Inicie sesión en http://localhost:3000 con el nombre de usuario harnessrouter y la contraseña harnessrouter. Esas credenciales aparecen en el README porque son marcadores de posición, no secretos, y el contenedor muestra una advertencia en cada inicio hasta que las cambie:

using the DEFAULT password. Set HR_AUTH_PASSWORD, or change it from the profile page, before exposing this instance.

Cámbielas desde la página Profile o establézcalas al iniciar el contenedor para un despliegue mediante script. HR_AUTH_USER y HR_AUTH_PASSWORD sustituyen los valores predeterminados.

docker run -d --name harnessrouter \
  -p 127.0.0.1:3000:3000 \
  -v harnessrouter:/data \
  -e HR_AUTH_USER='you' \
  -e HR_AUTH_PASSWORD='the-password-you-chose' \
  harnessrouter/harnessrouter

No hay correo de restablecimiento porque no existe un sistema de cuentas ni un servidor de correo. Si pierde la contraseña, elimine el archivo de autenticación del volumen y reinicie. Después, vuelva a iniciar sesión con los valores predeterminados.

docker stop harnessrouter
docker run --rm -v harnessrouter:/data alpine rm -f /data/selfhost-auth.json
docker start harnessrouter

HR_AUTH_DISABLED=1 elimina por completo la pantalla de inicio de sesión. La guía de self-hosting indica que eso sólo es razonable en una máquina a la que nadie más pueda acceder. Un VPS con una dirección IP pública no es esa máquina, así que mantenga activada la pantalla de inicio de sesión salvo que ejecute esto en un portátil.

Compruebe la versión, porque las antiguas no tienen control de acceso

Esta es la parte que debe tomarse en serio. Las versiones 0.1.x y 0.2.0 se publicaron sin ningún control de autenticación: cualquiera que pudiera acceder al puerto 3000 ya estaba dentro de la consola. 0.3.0 fue la primera versión publicada con inicio de sesión. Esas etiquetas antiguas todavía están publicadas y se pueden descargar a fecha de 12 October 2026, por lo que una etiqueta antigua fijada, o un archivo compose copiado de un compañero, puede exponer hoy una consola sin control de acceso en un puerto público.

A fecha de 19 August 2026, la etiqueta publicada más reciente era 0.5.5, con fecha de 18 August 2026. El 12 October 2026, latest apuntaba a 0.32.9, publicada el 11 October 2026, y sus candidatos de publicación 0.33.0 ya estaban publicados. Compruebe qué versión tiene y compárela con la lista de etiquetas de Docker Hub:

docker image ls harnessrouter/harnessrouter

Cualquier versión inferior a 0.3.0 debe sustituirse ahora, no programarse para más adelante. Las versiones iguales o superiores también requieren cambiar la contraseña, porque para alguien que analiza el puerto 3000 una contraseña predeterminada y ninguna contraseña son lo mismo. No considere actuales los números de versión de esta página. Eran válidos en las fechas indicadas, y este proyecto publica versiones rápidamente.

Conectar un proveedor

Nada funciona hasta que se conecta un proveedor de modelos. Añada uno desde la página Integrations de la consola o páselo a docker run en el entorno. El valor es JSON, por lo que debe entrecomillarlo en el shell:

-e HR_SECRET_GLOBAL_HARNESS_CONN_ANTHROPIC='{"name":"anthropic","provider":"anthropic","api_key":"sk-ant-…"}'

.env.example nombra una variable de conexión para cada familia de proveedores: HR_SECRET_GLOBAL_HARNESS_CONN_ANTHROPIC para el backend claude-code, HR_SECRET_GLOBAL_HARNESS_CONN_OPENAI para el backend codex, HR_SECRET_GLOBAL_HARNESS_CONN_GOOGLE para el backend gemini y HR_SECRET_GLOBAL_HARNESS_CONN_CUSTOM para cualquier endpoint compatible con OpenAI, que es donde se configura un agregador o su propio servidor de inferencia. Las variables HR_SECRET_GLOBAL_HARNESS_POLICY_CLAUDE, HR_SECRET_GLOBAL_HARNESS_POLICY_CODEX y HR_SECRET_GLOBAL_HARNESS_POLICY_HERMES correspondientes indican qué conexión usa cada backend de forma predeterminada, y hay una variable de política para cada backend. HR_SECRET_KEY es algo distinto. .env.example todavía lo describe como necesario sólo para conectar una base de datos a un agente, y la guía actual también pide configurarlo antes de conectar un destino de HarnessRouter Cloud y conservar la misma clave entre reinicios y actualizaciones.

HR_BACKENDS selecciona los backends que se instalan y cargan, como en HR_BACKENDS=claude,codex,hermes. Si no se configura, las versiones actuales instalan una lista predeterminada mucho más larga, de aproximadamente dos docenas de backends, desde claude, codex y hermes hasta opencode, gemini, goose y otros. Reducirla ahorra espacio en disco y tiempo durante el primer arranque. La guía actual de instalación autónoma indica que se debe «omitir cualquiera de ellos de HR_BACKENDS si no se va a usar», y su propio ejemplo reducido es HR_BACKENDS=opencode, que omite Hermes por completo. Si un backend no se puede instalar, el fallo no es fatal: los demás siguen funcionando y una tarea asignada a un backend que no se instaló falla en su primer turno, mientras el registro del contenedor indica qué instalación falló. Las versiones anteriores eran menos tolerantes. El archivo README de 0.5.5 probado aquí incluía un problema conocido: cualquier valor que omitiera hermes hacía que el contenedor terminara inmediatamente con el estado 1 y sin mostrar ningún mensaje de error. Por tanto, en una etiqueta tan antigua, deje HR_BACKENDS sin configurar o actualice. Si Hermes es el único harness que quiere usar, ejecutar el agente Hermes en su propio VPS requiere una instalación más pequeña.

Llamar a la API sin la consola

La consola es opcional. La misma API sirve para ambas opciones y utiliza un contrato de estilo Responses. Inicie sesión primero para obtener una cookie de sesión:

curl -c hr.cookies http://localhost:3000/api/selfhost/login \
  -H 'content-type: application/json' \
  -d '{"username":"harnessrouter","password":"your-password"}'

Después, envíe una tarea. Especifique el harness en metadata.harness_id y un modelo que su proveedor conectado realmente ofrezca:

curl -s -b hr.cookies http://localhost:3000/api/harness/v1/responses \
  -H 'content-type: application/json' \
  -d '{"input":"Reply with exactly this and nothing else: it works.",
       "metadata":{"harness_id":"codex"},
       "model":"gpt-5.4-mini",
       "stream":false}'

Un objeto JSON que contiene un bloque de salida y un recuento de tokens indica que el harness se ejecutó. Al cambiar harness_id de codex a claude-code, la misma solicitud se envía a otro harness. Ese cambio es el motivo principal de la existencia de este software. Tenga en cuenta que el id es claude-code, aunque el nombre del backend en HR_BACKENDS sea claude y la variable de política sea claude. La conexión personalizada anterior permite indicar a un harness un endpoint compatible con OpenAI que ya aloje, como se configura un harness de DeepSeek autoalojado en un VPS.

Acceda desde su portátil sin publicar un puerto

Hay dos formas y ninguna expone directamente un puerto de 0.0.0.0.

Un túnel SSH es la opción más sencilla y no requiere instalar nada en el servidor. Reenvía un puerto local de su equipo al loopback de la VPS.

ssh -N -L 3000:127.0.0.1:3000 you@your-vps

Mantenga el túnel abierto y acceda a http://localhost:3000 desde el navegador. Si SSH muestra bind: Address already in use, otro proceso de su portátil ya utiliza el puerto 3000. Elija otro puerto local con -L 3100:127.0.0.1:3000 y acceda al puerto 3100.

Un reverse proxy con terminación TLS es la opción adecuada cuando otras personas necesitan acceso. El proxy gestiona el certificado TLS (transport layer security) y reenvía las peticiones al loopback. La guía de self-hosting proporciona una configuración de Caddy:

console.example.com {
    encode zstd gzip
    reverse_proxy 127.0.0.1:3000 {
        flush_interval -1      # agent turns stream for minutes; never buffer them
    }
}

flush_interval -1 es la línea que suele omitirse. Agent transmite tokens durante varios minutos y un proxy que almacena en búfer la respuesta retiene esos tokens hasta que termina el turno. Por eso la consola parece bloqueada y después muestra todo de una vez. El equivalente en Nginx es proxy_buffering off; dentro del bloque location. Elija la opción que prefiera, pero mantenga el nombre DNS apuntando al proxy y el contenedor en el loopback. Comparación de Nginx, Caddy y Traefik como reverse proxy explica cuál se adapta mejor a su servidor.

Ejecutarlo con un usuario propio, no como root

El daemon de Docker se ejecuta como root, y pertenecer al grupo docker equivale a tener privilegios de root, porque un miembro puede iniciar un contenedor que monte el sistema de archivos del host. Por tanto, «añadir el equipo al grupo docker» concede acceso de root en el servidor que almacena la clave del proveedor.

La opción sencilla es crear una cuenta de servicio propietaria del archivo compose y de .env, y mantener esos archivos fuera de cualquier directorio de inicio compartido.

sudo adduser --disabled-password --gecos "" harness
sudo install -d -o harness -g harness -m 750 /srv/harnessrouter

No intente conseguirlo añadiendo --user a docker run ni user: al archivo compose. La guía actual indica que el contenedor debe iniciarse como root, y desde 0.8.2 se niega a iniciarse de cualquier otra forma. El registro muestra una sola línea que lo indica.

La opción más segura es usar Docker rootless, donde el propio daemon se ejecuta con ese usuario sin privilegios. Requiere el paquete uidmap para newuidmap y newgidmap, además de al menos 65536 UID subordinados en /etc/subuid y /etc/subgid para el usuario. uidmap está disponible en el archivo de Ubuntu, pero docker-ce-rootless-extras no. Este paquete se publica en el repositorio apt propio de Docker, en download.docker.com, que añade la instalación de Docker Engine. Si no ha instalado el engine desde ese repositorio, grep -rl download.docker.com /etc/apt/sources.list.d/ no muestra ninguna salida y la instalación siguiente no encontrará el paquete.

sudo apt install -y uidmap docker-ce-rootless-extras
sudo loginctl enable-linger harness
sudo -iu harness
dockerd-rootless-setuptool.sh install
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
systemctl --user enable --now docker

loginctl enable-linger no es opcional en este caso. Sin él, la instancia de systemd del usuario se detiene cuando termina la última sesión y el contenedor se detiene al cerrar la sesión. Confirme el resultado con docker info, que muestra rootless en Security Options. El modo rootless no puede enlazar puertos inferiores a 1024 sin configuración adicional. Esto no importa aquí porque el puerto 3000 está por encima de ese límite. La configuración de la cuenta se explica en crear usuarios con privilegios mínimos en un VPS.

Qué falla y qué verá

El contenedor se cierra un segundo después de iniciarse y los registros están vacíos. docker ps -a muestra Exited (1). En 0.5.5 y otras etiquetas antiguas, ese es el problema de HR_BACKENDS descrito arriba: el valor no incluía hermes. Añádalo de nuevo o actualice. Las versiones actuales no fallan de esta forma. En una etiqueta reciente, lea en su lugar la última línea de docker logs: desde 0.8.2, un contenedor iniciado con --user se cierra y muestra una línea que indica que debe iniciarse como root.

El primer inicio nunca termina. El registro se detiene después de una línea de installing y ready on :3000 nunca aparece. El equipo no puede acceder a la red para descargar las CLI de los agentes porque no están incluidas en la imagen. En las versiones actuales, el síntoma es menos grave: el registro muestra las instalaciones fallidas y estas faltan en la línea de backends available:. En ambos casos, corrija la ruta de salida o la configuración del proxy y reinicie.

La consola carga, pero todas las tareas fallan. No hay ningún proveedor conectado. La imagen no incluye un modelo integrado ni un nivel gratuito, por lo que una instancia nueva puede permitirle iniciar sesión y aun así no ejecutar nada.

La consola se bloquea a mitad de la respuesta detrás de un proxy. La salida aparece en un solo bloque cuando termina el turno. Se trata de un almacenamiento en búfer de la respuesta. Configure flush_interval -1 en Caddy o proxy_buffering off; en Nginx.

No puede acceder desde su portátil y el túnel está activo. Ejecute docker port harnessrouter en el servidor. Si no muestra nada, el contenedor no publica ningún puerto porque se inició sin -p.

¿Merece la pena ejecutarlo?

Merece la pena si realmente usa más de un harness y quiere un solo endpoint y un único almacén de credenciales en lugar de tres de cada uno. También merece la pena si está desarrollando un producto sobre esta base y quiere que el harness sea un valor de configuración en lugar de tener que reescribirlo. Eso es lo que proporciona UHP, con la salvedad indicada arriba sobre lo reciente que es el protocolo.

No merece la pena si usa un solo harness. Instalar esa CLI en el servidor implica menos componentes, y no hay ningún inicio de sesión entre usted y ella. Tampoco es el enfoque adecuado si quiere varios agentes que colaboren en una tarea, en lugar de una API delante de varios harnesses; para ese caso se necesita otra herramienta: consulte un harness multiagente como Omnigent. En cualquier caso, las reglas de despliegue no cambian. Vincúlelo a loopback, cambie la contraseña, use una etiqueta fijada en 0.3.0 o superior y ejecútelo con su propio usuario.

FAQ

¿Es seguro publicar HarnessRouter en el puerto 3000?

No. La consola crea harnesses, lee todas las transcripciones, ejecuta agentes con acceso al shell y al sistema de archivos, y almacena la clave del proveedor que conectó, por lo que un puerto abierto expone todo esto. Publique el servicio en loopback con -p 127.0.0.1:3000:3000 y acceda a él mediante un túnel SSH o un reverse proxy con terminación TLS. Un firewall del host no basta por sí solo: Docker escribe sus propias reglas en la tabla del kernel nat, por lo que un puerto publicado responde desde Internet aunque ufw lo muestre como denegado. Verifíquelo con sudo ss -ltnp | grep 3000, que debería imprimir 127.0.0.1:3000.

¿Qué versión de HarnessRouter añadió la pantalla de inicio de sesión?

0.3.0. Las versiones 0.1.x y 0.2.0 se publicaron sin ninguna autenticación y, a fecha del 12 de octubre de 2026, ambas siguen publicadas y se pueden descargar, por lo que quien las ejecute depende de que nadie encuentre el puerto. A fecha del 19 de agosto de 2026, la etiqueta más reciente era 0.5.5, fechada el 18 de agosto de 2026; el 12 de octubre de 2026, latest apuntaba a 0.32.9. Ejecute docker image ls harnessrouter/harnessrouter para ver qué versión tiene, compare ese resultado con la lista de etiquetas de Docker Hub y no con esta página, y cambie la contraseña predeterminada incluso en una versión actual.

¿Por qué el contenedor se detiene justo después de establecer HR_BACKENDS?

En una versión actual no debería hacerlo. La guía de autoalojamiento indica que debe omitir cualquier backend que no vaya a utilizar, y que un backend cuya instalación falle no es un error fatal. La salida era un problema conocido en versiones anteriores, incluida 0.5.5, sobre la que se probó inicialmente esta página. En esa versión, cualquier valor que omitiera hermes terminaba con el estado 1 y sin mostrar ningún mensaje de error. Si ve Exited (1) en docker ps -a con una etiqueta tan antigua, vuelva a añadir hermes, como en HR_BACKENDS=claude,codex,hermes, o actualice. En una etiqueta reciente, lea docker logs: desde 0.8.2, un contenedor iniciado con --user termina con una línea que indica que debe iniciarse como root.

¿Necesita HarnessRouter acceso a Internet durante el primer arranque?

Sí. Las CLI de los agentes se descargan durante el primer arranque en lugar de incluirse en la imagen, porque cada una tiene su propia licencia. En 0.5.5, un equipo sin ruta de salida mostró las líneas installing y después nunca llegó a ready on :3000; las versiones actuales identifican en el registro las instalaciones que fallan. Las CLI instaladas se almacenan en caché en el volumen, por lo que los arranques posteriores suelen ser más rápidos y no necesitan red aparte del proveedor de modelos conectado, salvo que habilite un backend nuevo o que alguno no se haya instalado anteriormente.

He perdido la contraseña de la consola. ¿Cómo puedo volver a acceder?

No hay ningún correo de restablecimiento porque no existe un sistema de cuentas ni un servidor de correo. Detenga el contenedor, elimine /data/selfhost-auth.json del volumen, vuelva a iniciarlo, inicie sesión con las credenciales predeterminadas y establezca una contraseña nueva desde la página Profile. Si tanto el contenedor como el volumen se llaman harnessrouter, ejecute docker stop harnessrouter, después docker run --rm -v harnessrouter:/data alpine rm -f /data/selfhost-auth.json y, por último, docker start harnessrouter.