AI-translated from English; not yet reviewed by a fluent editor.

# Ejecuta una pasarela Hermes Agent en un VPS y comprueba una respuesta privada de Telegram

> Configura una pasarela Hermes Docker con versión comprobada en un VPS Linux, permite un remitente privado de Telegram, verifica una respuesta real y comprueba reinicio y parada.

By BIG CHANGE Editorial

Published: 2026-10-19T20:31:34.981Z
Updated: 2026-10-19T20:31:34.981Z
Canonical: https://bigchange.ai/blog/hermes-vps-docker-private-telegram-first-reply

![Conceptual charcoal illustration of one hand holding an unbranded phone with two blank message shapes on its screen.](https://bigchange.ai/api/media/file/hermes-private-reply-check-hero-v1.png)
AI-generated conceptual illustration by BIG CHANGE; no actual Telegram interface, Hermes deployment or observed reply is depicted.

Un bot privado de Telegram facilita acceder a un agente en un VPS, pero conectar la pasarela no demuestra que responda a la persona prevista. Partimos de un directorio nuevo de Hermes Agent, permitimos un ID numérico, comprobamos una respuesta real y dejamos una parada verificada. Seguimos las [instrucciones Docker v0.22.2](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/docker.md) y [instrucciones Telegram](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/messaging/telegram.md) de NousResearch, comprobadas el 19 de octubre de 2026. BIG CHANGE no ejecutó un VPS, descargó la imagen, creó un bot ni llamó a un modelo para esta guía.

## El gran cambio

- **Qué cambia:** Una imagen Docker fijada por digest y verificada por versión, con un montaje dedicado `/opt/data`, permite identificar el software y estado de esta pasarela.
- **Por qué importa:** Una lista de ID numéricos permitidos y una respuesta privada real muestran si la cuenta prevista puede usarla.
- **Qué vigilar:** El emparejamiento o los permisos globales amplían el acceso; una petición inocua no limita las herramientas del agente. Revisa permisos, registros, reinicio y parada.

Necesitas autoridad para administrar un VPS Linux por SSH, Docker Engine funcionando y acceso de recuperación al servidor, una cuenta Telegram capaz de crear un bot en BotFather y una cuenta elegible del proveedor de modelos Hermes. Contrasta arquitectura y recursos con la imagen oficial amd64 o arm64 y consulta acceso y facturación antes del asistente. Se presupone Docker operativo; instalación y cortafuegos dependen de SO y proveedor. El host necesita salida a Telegram y al proveedor. Reserva un directorio privado para el estado y limita sus lectores: `/opt/data` guardará credenciales, sesiones y registros. [El manual Docker](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/docker.md) lo considera la fuente persistente de referencia.

## 1. Fija la imagen antes de configurar

Conecta por SSH y conserva el mismo shell para los comandos. La etiqueta `stable` puede cambiar. Descarga la imagen, registra el digest del repositorio y confirma que la propia imagen indica la versión `0.22.2`. Detente si cambia, falta el digest, hay estado previo o existe un contenedor llamado `hermes`. Actualiza las instrucciones para la versión real o consigue una imagen documentada correspondiente antes de seguir. El digest fija la imagen, pero por sí solo no prueba su versión.

```sh
set -eu
docker info >/dev/null
docker container inspect hermes >/dev/null 2>&1 && { echo 'Container hermes already exists; stop here.'; exit 1; }
HERMES_DATA="$HOME/.hermes"
if [ -e "$HERMES_DATA" ]; then echo 'Hermes data path already exists; stop here.'; exit 1; fi
mkdir -m 700 "$HERMES_DATA"
docker pull nousresearch/hermes-agent:stable
docker image inspect nousresearch/hermes-agent:stable --format '{{json .RepoDigests}}'
IMAGE_REF="$(docker image inspect nousresearch/hermes-agent:stable --format '{{index .RepoDigests 0}}')"
if ! printf '%s\n' "$IMAGE_REF" | grep -Eq '^nousresearch/hermes-agent@sha256:[0-9a-f]{64}$'; then
  echo 'No valid repository digest; stop here.'; exit 1
fi
printf 'Pinned image: %s\n' "$IMAGE_REF"
VERSION_OUTPUT="$(docker run --rm "$IMAGE_REF" --version)"
printf 'Image version: %s\n' "$VERSION_OUTPUT"
if ! printf '%s\n' "$VERSION_OUTPUT" | grep -Eq '(^|[^0-9])v?0[.]22[.]2([^0-9]|$)'; then
  echo 'Image version is not 0.22.2; stop here.'; exit 1
fi
```

`set -eu` detiene esta secuencia si Docker no está disponible, falla la descarga o inspección, o falla el comando de versión. Las comprobaciones explícitas paran también ante digest vacío u otra versión. No sigas a la configuración tras esos resultados. Guarda el valor `nousresearch/hermes-agent@sha256:…` registrado. Configuración y pasarela usan `IMAGE_REF`, así que un cambio posterior de etiqueta no cambia silenciosamente el contenedor. Son comprobaciones del lector en su VPS; el artículo no contiene un digest verificado. Usa un directorio nuevo y dedicado en el sistema de archivos nativo. Nunca ejecutes dos pasarelas contra los mismos datos.

## 2. Configura el proveedor y un remitente privado

Ejecuta el [asistente de configuración Docker](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/docker.md) con el directorio montado. Elige una ruta de modelo permitida, autentícate y revisa el proveedor/modelo resultante. Acceso y cargos dependen de la cuenta; guardar ajustes no prueba una petición exitosa.

```sh
docker run -it --rm -v "$HERMES_DATA:/opt/data" "$IMAGE_REF" setup
```

En Telegram solicita a [@BotFather](https://t.me/BotFather) un bot con `/newbot` y mantén su token privado. Obtén el **ID numérico Telegram del remitente**, por ejemplo mediante el método enlazado en el [manual Telegram](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/messaging/telegram.md); un nombre de usuario no es un ID. El asistente o `hermes gateway setup` escribe token y lista permitida. A mano, coloca `TELEGRAM_BOT_TOKEN=<private token>` y `TELEGRAM_ALLOWED_USERS=<your numeric ID>` en `$HERMES_DATA/.env`, que aparece como `/opt/data/.env` dentro del contenedor. No incluyas el token en comandos, historial, notas compartidas ni este artículo.

En `$HERMES_DATA/config.yaml` (`/opt/data/config.yaml` dentro del contenedor), define el comportamiento global para mensajes privados no autorizados:

```yaml
unauthorized_dm_behavior: ignore
```

Tras salir el contenedor de configuración, la imagen puede haber cambiado `$HERMES_DATA` a su UID de ejecución 10000. El arranque limita `.env` al modo `600` y restringe un `config.yaml` existente a `640`; uno creado por primera vez en ese arranque puede necesitar igual ajuste. Un usuario SSH normal podría no abrirlos. Si faltan claves, un **administrador autorizado del host** puede inspeccionar y editar esos dos archivos con `sudo` y restaurar propietario y modos privados. Un editor ejecutado como UID 10000 puede no atravesar un `$HOME` del usuario de acceso; por eso se usa administración del host. En un host con `sudo` y `vi`, úsalo después de verificar metadatos de propietario/modo sin secretos. No sigas con otro UID o archivo ausente; resuelve primero el acceso específico.

```sh
sudo stat -c '%u:%g %a %n' "$HERMES_DATA" "$HERMES_DATA/.env" "$HERMES_DATA/config.yaml"
# Expected: directory owner 10000 and mode 700; .env owner 10000 and mode 600.
# config.yaml should have owner 10000; its first-boot mode can vary.
sudo vi "$HERMES_DATA/.env"
sudo vi "$HERMES_DATA/config.yaml"
sudo chown 10000:10000 "$HERMES_DATA/.env" "$HERMES_DATA/config.yaml"
sudo chmod 700 "$HERMES_DATA"
sudo chmod 600 "$HERMES_DATA/.env"
sudo chmod 640 "$HERMES_DATA/config.yaml"
sudo stat -c '%u:%g %a %n' "$HERMES_DATA" "$HERMES_DATA/.env" "$HERMES_DATA/config.yaml"
```

La salida final de `stat` debe mostrar UID/GID 10000 en ambos archivos, modo del directorio `700`, `.env` con modo `600` y `config.yaml` con modo `640`. Muestra metadatos, no credenciales. El `chown` afecta solo a esos dos archivos, incluida una sustitución creada por el editor. Si no existe `sudo` o `vi`, sigue el procedimiento autorizado del host con igual lectura de propietario y modos. No hagas los datos legibles para todos ni reasignes el usuario del contenedor.

Conserva los ajustes del proveedor al editar. Ninguna anulación Telegram de `unauthorized_dm_behavior` debe establecer `pair`, ni un parámetro global `GATEWAY_ALLOWED_USERS` o `GATEWAY_ALLOW_ALL_USERS` conceder acceso más amplio. En `config.yaml`, comprueba también que ni `gateway.allow_all_users` ni el parámetro de nivel superior `allow_all_users` sean true y que no haya otro remitente global o Telegram. No uses `*` en las listas, añadas listas de grupos ni apruebes códigos de emparejamiento. Un directorio nuevo evita permisos heredados; si contiene datos, detente e inspecciona sin sobrescribir. Mantén la privacidad de grupos de BotFather, no añadas el bot a grupos ni lo hagas administrador. El [manual de acceso a la pasarela](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/messaging/index.md) separa listas permitidas y autorizaciones persistentes de emparejamiento. El [manual de seguridad](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/security.md) describe `ignore` como descarte silencioso de mensajes privados no autorizados.

La lista limita quién inicia conversaciones, no lo que hace el agente autorizado. Las sesiones Telegram de Hermes incluyen terminal por defecto. Revisa permisos, montajes, proveedor y política del host antes de admitir al remitente. Una petición de prueba inocua es solo una petición.

## 3. Inicia la pasarela y comprueba la primera respuesta

Inicia un contenedor con nombre desde el digest registrado. El comando publicado incluye un `-p 8642:8642` opcional para la API; omítelo, pues un mensaje privado no requiere API o panel públicos. La imagen supervisa la pasarela; la política Docker `unless-stopped` controla el reinicio al arrancar Docker. El montaje conserva configuración y sesiones tras reiniciar.

```sh
docker run -d --name hermes --restart unless-stopped \
  -v "$HERMES_DATA:/opt/data" "$IMAGE_REF" gateway run
if ! {
  docker inspect hermes --format '{{.Image}} {{.State.Status}}' &&
  [ "$(docker inspect hermes --format '{{.State.Status}}')" = running ] &&
  docker logs --tail 50 hermes &&
  docker exec -u hermes hermes hermes pairing list
}; then
  echo 'State, logs or pairing check failed; stopping before any message.'
  docker stop hermes || true
  docker inspect hermes --format '{{.State.Status}}' || true
  exit 1
fi
```

Confirma que el contenedor está `running`, examina conexión Telegram y errores del proveedor en los registros y consulta emparejamientos antes de enviar. Si falla una lectura inicial, el bloque detiene la pasarela y muestra estado; un resultado desconocido no autoriza seguir. Confirma `exited` antes de investigar, sin enviar ni reiniciar si hay incertidumbre. No debe existir otro remitente aprobado; si aparece, detén y comprueba la parada. `docker exec` no funciona contra un contenedor parado, y el punto de entrada normal puede restaurar una pasarela anterior. En instalación nueva con UID predeterminado, la comprobación sin conexión ejecuta solo la CLI Hermes fijada, como UID 10000 y sin red, evitando el arranque. Es adaptación de comandos y punto de entrada documentados, no un comando probado por BIG CHANGE. Úsala solo tras confirmar UID activo y propietario de datos 10000. Si hay dudas de propietario, UID, salida CLI o permisos, mantén parada hasta resolverlas antes de reiniciar.

```sh
if [ "$(docker exec -u hermes hermes id -u)" != 10000 ] || [ "$(stat -c %u "$HERMES_DATA")" != 10000 ]; then
  echo 'Runtime UID or data owner differs; stop for a host-specific repair.'; docker stop hermes; exit 1
fi
docker stop hermes
if [ "$(docker inspect hermes --format '{{.State.Status}}')" != exited ]; then
  echo 'Container is not exited; do not mount state in another container.'; exit 1
fi
docker run --rm --network none --user 10000:10000 \
  --entrypoint /opt/hermes/.venv/bin/hermes \
  -v "$HERMES_DATA:/opt/data" "$IMAGE_REF" pairing list
# For a listed unwanted Telegram user, read the exact numeric ID first:
printf 'Unwanted numeric Telegram user ID: '; IFS= read -r UNWANTED_ID
if ! printf '%s\n' "$UNWANTED_ID" | grep -Eq '^[0-9]+$'; then echo 'Invalid ID; leave gateway stopped.'; exit 1; fi
docker run --rm --network none --user 10000:10000 \
  --entrypoint /opt/hermes/.venv/bin/hermes \
  -v "$HERMES_DATA:/opt/data" "$IMAGE_REF" pairing revoke telegram "$UNWANTED_ID"
docker run --rm --network none --user 10000:10000 \
  --entrypoint /opt/hermes/.venv/bin/hermes \
  -v "$HERMES_DATA:/opt/data" "$IMAGE_REF" pairing list
```

Confirma que el ID no deseado ya no aparece. Inspecciona en privado `$HERMES_DATA/.env` y `config.yaml` para otras listas globales o de plataforma, `*` o ajustes de acceso total. Retira permisos por la configuración documentada. Mantén parada hasta revisar todas las vías. Quitar una entrada no revoca emparejamientos independientes o permisos globales. Después de comprobarlo, `docker start hermes` reanuda deliberadamente el contenedor original; revisa registros y lista antes de escribirle.

Desde la cuenta permitida abre un chat **privado** con el bot y envía algo inocuo, como «Responde con un saludo breve». Comprueba respuesta real y su registro o sesión. Mensaje enviado, escritura en curso, estado o configuración terminada no son una respuesta. El comando Telegram `/whoami` muestra el ámbito activo, no demuestra autorización del host. Guarda solo pruebas no sensibles.

Sin respuesta, lee primero estado y `docker logs --tail 50 hermes`. Comprueba token, valor numérico exacto de `TELEGRAM_ALLOWED_USERS`, autenticación y elegibilidad del modelo y salida de red. Ante resultado incierto lee chat y registros antes de repetir. El arranque en frío puede descartar actualizaciones pendientes y la supresión de duplicados es limitada en memoria. No se garantiza entrega exactamente una vez.

## 4. Comprueba reinicio, parada y recuperación

Terminado el primer turno, reinicia el mismo contenedor, revisa registros nuevos y el estado guardado en `/opt/data`, envía una petición privada inocua **nueva** y verifica su respuesta. Detén y lee el estado Docker. `exited` confirma parada; el silencio del chat no basta. `docker start hermes` reanuda intencionadamente más tarde.

```sh
docker restart hermes
docker logs --tail 50 hermes
docker inspect hermes --format '{{.State.Status}}'
# After the restarted gateway is ready, send a new private test message.
docker stop hermes
docker inspect hermes --format '{{.State.Status}}'
# Expected after stop: exited
# When intentionally resuming later: docker start hermes
```

Si falla el reinicio, revisa Docker, después `$HERMES_DATA/logs/gateways/default/current` y `$HERMES_DATA/logs/container-boot.log`, montaje, propietario e imagen/versión fijadas. Las [notas v0.22.2](https://github.com/NousResearch/hermes-agent/releases/tag/v0.22.2) describen una corrección de actividad al arrancar, sin establecer qué pasó en tu host. No borres el estado para reparar. Si se filtra el token, detén, revócalo en BotFather, cámbialo en privado en el archivo montado `.env` y revisa acceso antes de reiniciar. Revoca emparejamientos no deseados y revisa listas efectivas.

Alojamiento y modelo pueden cobrar por separado. Consulta plan, límites y cargos reales; no se prometen tiempo, cuota gratuita o disponibilidad. Telegram y el proveedor procesan los mensajes; el host guarda secretos y estado. Solo se comprueba primera respuesta de un host y bot. Otras guías BIG CHANGE cubren [copia y recuperación de Hermes](https://bigchange.ai/blog/hermes-encrypted-github-backup-recovery-guide) y [un trabajo periódico de Hermes](https://bigchange.ai/blog/hermes-skill-recurring-job-first-run).

## Fuentes y lecturas adicionales

La [configuración Docker](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/docker.md), [configuración Telegram](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/messaging/telegram.md), [guía de acceso](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/messaging/index.md), [guía de seguridad](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/security.md) y [versión v0.22.2](https://github.com/NousResearch/hermes-agent/releases/tag/v0.22.2) son fuentes primarias de NousResearch. El [inicio rápido](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/getting-started/quickstart.md) explica el proveedor. Documentan el procedimiento, no una ejecución de VPS o bot de BIG CHANGE.

## Sources

- [Versión Hermes Agent v0.22.2](https://github.com/NousResearch/hermes-agent/releases/tag/v0.22.2) — Fecha y corrección documentada de actividad de arranque.
- [Configuración Docker Hermes, v0.22.2](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/docker.md) — Canales de imagen, montaje, configuración, supervisión, puerto y registros.
- [Dockerfile oficial, v0.22.2](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/Dockerfile) — Entrada, UID, HERMES_HOME y ruta CLI para comprobación limitada sin conexión.
- [Hook Docker de segunda fase, v0.22.2](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/docker/stage2-hook.sh) — Propiedad de datos y permisos .env/config tras configurar.
- [Configuración Telegram, v0.22.2](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/messaging/telegram.md) — BotFather, token, lista numérica, privacidad y límites de entrega.
- [Mensajería y pasarela, v0.22.2](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/messaging/index.md) — Acceso efectivo, lectura de emparejamiento y revocación.
- [Seguridad, v0.22.2](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/user-guide/security.md) — Mensajes privados no autorizados y límites de acceso.
- [Inicio rápido, v0.22.2](https://raw.githubusercontent.com/NousResearch/hermes-agent/v0.22.2/website/docs/getting-started/quickstart.md) — Ruta de configuración del proveedor.
