Files
hermes-webui-docker/references/host-gateway-config.md
T
2026-09-06 13:50:57 +00:00

4.7 KiB

Host Gateway API Server Configuration — Hermes WebUI Hybrid

The Problem

WebUI shows "Check HERMES_WEBUI_GATEWAY_BASE_URL and Gateway API server health". Gateway systemd service shows active (running) but port 8642 isn't listening.

Root Cause

api_server is a gateway platform (enum Platform.API_SERVER = "api_server"), not a standalone service. It activates only when configured — either via config.yaml or env vars. On a host-native (systemd) setup, env vars from the Docker .env file are NOT propagated.

Fix — Two Options

# At ROOT level of /home/estorozhenko/.hermes/config.yaml
platforms:
  api_server:
    enabled: true
    host: 0.0.0.0
    port: 8642
    key: "7c8a2d9f4e1b3a5c6d7e8f9a0b1c2d3e4f5a6b7c"

⚠️ Field name note: The field must be key (not api_key). The adapter reads extra.get("key", os.getenv("API_SERVER_KEY", "")). A field named api_key in the YAML is silently ignored because the bridge only moves key into the extra dict.

Option B: systemd unit env vars

Environment="API_SERVER_ENABLED=true"
Environment="API_SERVER_HOST=0.0.0.0"
Environment="API_SERVER_KEY=7c8a2d9f4e1b3a5c6d7e8f9a0b1c2d3e4f5a6b7c"

Then daemon-reload + restart.

How the Code Works

From gateway/config.py:

  1. _load_env_overrides (line ~2128): reads API_SERVER_ENABLED, API_SERVER_KEY, API_SERVER_HOST, API_SERVER_PORT, API_SERVER_CORS_ORIGINS from env
  2. Platform connected checker (line ~846): requires key in extra with min_length=16
  3. YAML bridging (line ~1471): moves port, key, host, cors_origins, model_name from the platform dict into extra so PlatformConfig preserves them
  4. _has_usable_api_server_key (line ~822): checks key is a string ≥ 16 chars

Without a valid key (≥16 chars), the platform won't be marked connected and the adapter won't start — no listener on 8642, no error message.

Key Debugging Lesson: Multi-Source Divergence

The API server key lives in four independent sources that must all agree:

Source Where How it's set
config.yaml platforms.api_server.key Edited directly
~/.hermes/.env API_SERVER_KEY=... hermes config set gateway.api_server_key ... or manual edit
systemd unit Environment="API_SERVER_KEY=..." hermes gateway install --force or manual edit
docker .env for webui API_SERVER_KEY=... Docker compose env-file

Common failure modes:

  • config.yaml says one thing, .env says another → .env wins (os.environ is overwritten at startup), so even though systemd's Environment= and config.yaml agree, the process env is different. This is the most frequent root cause of "401 with correct key".
  • systemd shows key A, .env shows key B → process starts with systemd's env, but then load_gateway_config reads .env and calls os.environ["API_SERVER_KEY"] = B, overwriting A.

To fix: pick ONE canonical value and set it identically in all four sources. The simplest approach: pick a single key string (e.g. 40 hex chars), put it in config.yaml's key: field, and ensure ~/.hermes/.env, the systemd unit, and docker .env all match.

How to Verify All Sources

# 1. Config YAML
grep -A1 'key:' ~/.hermes/config.yaml | grep -v extra

# 2. User .env (read_file blocked — use terminal/xxd)
grep API_SERVER_KEY ~/.hermes/.env

# 3. Systemd service
grep API_SERVER_KEY /etc/systemd/system/hermes-gateway.service

# 4. Docker compose .env
grep API_SERVER_KEY /opt/hermes/docker/.env

# 5. Live process env (verify the actual value the gateway uses)
SYSTEMD_PID=$(systemctl show hermes-gateway.service -p MainPID | grep -oP '\d+')
cat /proc/$SYSTEMD_PID/environ | tr '\0' '\n' | grep API_SERVER_KEY

All five should show the identical value. If step 5 (live process) differs from 1-4, then something is overwriting the key at runtime — likely step 2.

Verification

# Confirm listener
ss -tlnp | grep 8642

# Health check
curl -s http://localhost:8642/health
# → {"status": "ok", "platform": "hermes-agent", "version": "0.19.0"}

# From inside webui container
docker exec hermes-webui curl -s http://host.docker.internal:8642/health

# Check gateway logs for platform startup
journalctl -u hermes-gateway.service --no-pager -n 10 | grep -i api

Env Vars Expected by WebUI

In docker-compose.yml the webui expects:

- HERMES_WEBUI_GATEWAY_API_KEY=${API_SERVER_KEY:-}
- HERMES_API_URL=http://host.docker.internal:8642
- HERMES_WEBUI_GATEWAY_BASE_URL=http://host.docker.internal:8642

The API_SERVER_KEY env var must be exported or set in the .env file that docker-compose reads.