Saltar al contenido
Volver al blog
IADockerSelf-hosting

LobeHub lleva los chats autoalojados al gateway de servidor

La actualización v2.2.18 cambia el despliegue autoalojado y obliga a revisar claves, tokens, URLs y proxy inverso.

Ismael Catala4 min de lectura

El navegador deja de cargar con todo el trabajo

LobeHub v2.2.18 cambia un detalle importante en los despliegues con Docker Compose: los chats pasan a usar Gateway Mode en el servidor por defecto. No es una opción estética ni una nueva pantalla de configuración. El navegador mantiene una conexión WebSocket con el gateway, mientras que el servidor ejecuta y empuja los eventos de las operaciones de agentes.

Para un homelab, esto separa mejor las piezas. LobeHub ya no depende de que el navegador sea quien lleve el ciclo principal de ejecución del chat. El gateway queda como un servicio más del stack, con su propia red, su token de servicio y una superficie HTTP y WebSocket que puedo enrutar mediante Caddy.

Lo que hay que migrar al actualizar Compose

Actualizar la imagen no basta si el despliegue venía de una versión anterior. La configuración necesita una clave JWKS_KEY propia del despliegue, su versión pública en JWKS_PUBLIC_KEY, un GATEWAY_SERVICE_TOKEN y una URL pública para AGENT_GATEWAY_URL. Además, AGENT_GATEWAY_INTERNAL_URL permite que el contenedor principal contacte con el gateway por la red interna de Compose sin depender de la ruta pública.

La parte delicada es no entregar la clave privada al gateway. El contenedor de LobeHub conserva JWKS_KEY, que firma los JWT internos, y el gateway recibe únicamente JWKS_PUBLIC_KEY para verificarlos. El token de servicio protege las llamadas internas hacia las rutas de operaciones del gateway, así que debe ser un secreto distinto y no una cadena reutilizada de otro servicio.

Este es un extracto reducido de la estructura que usaría en Compose. Los valores reales deben vivir fuera del archivo versionado, por ejemplo en .env o en un gestor de secretos, y las URLs tienen que coincidir con el dominio que verá el navegador.

services:
  lobe:
    environment:
      ENABLE_AGENT_GATEWAY: "1"
      AGENT_GATEWAY_URL: https://gateway.example.com
      AGENT_GATEWAY_INTERNAL_URL: http://gateway:8787
      GATEWAY_SERVICE_TOKEN: ${GATEWAY_SERVICE_TOKEN}
      JWKS_KEY: ${JWKS_KEY}
 
  gateway:
    image: ghcr.io/lobehub/lobehub-gateway:0.3.2
    environment:
      SERVICE_TOKEN: ${GATEWAY_SERVICE_TOKEN}
      JWKS_PUBLIC_KEY: ${JWKS_PUBLIC_KEY}
      LOBE_API_BASE_URL: https://lobe.example.com

Dos rutas para un mismo servicio

La URL pública y la interna resuelven un problema habitual de Docker. AGENT_GATEWAY_URL debe ser alcanzable desde el navegador porque también será el origen del WebSocket. En cambio, AGENT_GATEWAY_INTERNAL_URL puede apuntar directamente al nombre del servicio, como http://gateway:8787, y evita que el contenedor tenga que salir hacia su propio proxy inverso.

Si uso un subdominio específico, Caddy puede exponer el gateway sin una configuración especial para WebSocket. La directiva reverse_proxy gestiona la actualización de la conexión, pero no conviene aplicar límites agresivos de lectura o escritura: un agente puede mantener el socket abierto durante una operación larga.

gateway.example.com {
    reverse_proxy gateway:8787
}

También es posible publicar el gateway bajo un prefijo de ruta, pero ahí hay que comprobar que el proxy elimine ese prefijo antes de enviar la petición. El gateway espera recibir rutas como /ws y /api/operations/* desde su raíz. Un proxy que reenvíe /agent-gateway/ws sin transformarlo romperá la conexión aunque el contenedor esté sano.

La letra pequeña antes de pulsar actualizar

Esto no convierte el gateway en una plataforma distribuida. La implementación Go documentada para autoalojamiento mantiene operaciones, eventos pendientes y otros datos de ejecución en memoria, así que un reinicio pierde ese estado. También exige que las llamadas del backend y el WebSocket del navegador para una misma operación lleguen a la misma instancia.

Tampoco conviene interpretar Gateway Mode como aislamiento completo de un agente. El gateway ordena el tráfico entre navegador y servidor, pero las credenciales de modelos, las herramientas habilitadas y los permisos siguen necesitando su propia revisión. Separar contenedores ayuda a delimitar responsabilidades, no sustituye la gestión de secretos ni una política de acceso razonable.

Antes de actualizar, haría copia de la base de datos y guardaría el docker-compose.yml y el .env actuales. La propia versión advierte de que la migración y la reversión completas no se han verificado como una garantía general. Si faltan las variables del gateway, LobeHub avisa al arrancar y los chats vuelven a ejecutarse en el navegador, lo cual evita una caída total pero puede ocultar una migración incompleta.


Fuente: LobeHub v2.2.18 Documentación oficial: LobeHub Agent Gateway para Go