hermes-webui — operate, upgrade, troubleshoot¶
The Hermes Agent web front-end on vps-apps. Mesh-only, runs in-process on the
shared fleet home — full parity (profile chips, CLI session bridge,
memory/skills/cron panels). The compose + Dockerfile are
tracked in the repo at vps-apps/hermes-webui/ as a mirror; the live
instance (source of truth) is /opt/docker/hermes-webui/ on vps-apps.
| fact | value |
|---|---|
| URL (mesh only) | http://100.64.0.100:8788 |
| Container | hermes-webui, local image hermes-webui:v0.52.113-local |
| Live dir | /opt/docker/hermes-webui (compose.yml, Dockerfile, .env, src/, hermes-agent/, workspace/) |
| Agent home | /opt/homelab-data/hermes mounted as .hermes — the REAL fleet home (uid 1001 shared) |
| Vendored agent | hermes-agent/ = hermes-agent 0.21.1, streamed from the fleet image; pip-installed at init (HERMES_WEBUI_AUTO_INSTALL=1, issue #570) |
| Chat | in-process; HERMES_API_URL (gateway loopback 8642) only feeds the Tasks/cron health probe |
| Auth | HERMES_WEBUI_PASSWORD in the live .env (chmod 600); passkeys optional via Settings → System |
| Networks | network_mode: host; the server binds only the Netbird IP — never 0.0.0.0 |
Mode caveats: - Sessions started from the WebUI execute tools inside the webui container (upstream limitation #681) — fewer mounts than the hermes container, so heavy fleet work stays in CLI/gateway sessions. - Settings → Providers in the WebUI writes the REAL fleet config. - Keep the vendored agent version aligned with the fleet image; skew means two config-migration versions writing one home.
Why the local build: ghcr publishes only ≤0.50.43, which predates the
in-process/gateway-chat features; src/ vendors nesquena/hermes-webui
v0.52.113. The hermes-agent/ dir is NOT an upstream clone — it is the agent
source streamed out of the running fleet image (exact version match);
the init script pip-installs its base deps at container start.
Access from PC / phone¶
- Both devices on Netbird, then open
http://100.64.0.100:8788and log in with the.envpassword. - Android: "Add to Home screen" installs the PWA. Caveat: Chrome only
offers PWA install / service worker / voice input on HTTPS or localhost.
On plain
http://<mesh-ip>the install prompt may never appear — that is the cause, not a break. Workaround if wanted:chrome://flags→unsafely-treat-insecure-origin-as-secure→http://100.64.0.100:8788. - Do NOT put basic auth or another reverse proxy in front: proxy basic auth
breaks the installed PWA's service-worker update fetches (upstream
docs/troubleshooting.md).
Upgrade the webui¶
ssh vps-apps
cd /opt/docker/hermes-webui
# 1. re-vendor the webui source at the target tag
git clone --depth 1 --branch <new-tag> https://github.com/nesquena/hermes-webui /tmp/hwi
rsync -a --delete /tmp/hwi/ src/ && rm -rf /tmp/hwi
# (only src/docker_init.bash, scripts/, api/, static/ ... — whatever the
# new tag ships; the Dockerfile COPYs all of src/)
# 1b. bump the version stamp in BOTH places (they must agree)
# Dockerfile: ARG HERMES_VERSION=vX.Y.Z-local
# compose.yml: image: hermes-webui:vX.Y.Z-local
# 2. re-vendor the agent source FROM THE FLEET IMAGE (keeps version parity)
# — after the fleet image was pulled and the gateway recreated:
docker exec hermes tar -C /opt/hermes -cf - \
--exclude=./.venv --exclude=./node_modules --exclude=./.git . \
| tar -C /opt/docker/hermes-webui/hermes-agent.new -xf -
chown -R 1001:1001 /opt/docker/hermes-webui/hermes-agent.new
mv /opt/docker/hermes-webui/hermes-agent /opt/docker/hermes-webui/hermes-agent.old
mv /opt/docker/hermes-webui/hermes-agent.new /opt/docker/hermes-webui/hermes-agent
# 3. rebuild + restart only this stack
docker compose build && docker compose up -d
# 4. verify
docker logs hermes-webui 2>&1 | grep -E "Agent dependencies|config file"
# expect: "Agent dependencies installed successfully" and
# "config file: /home/hermeswebui/.hermes/profiles/<active>/config.yaml (found)"
docker inspect --format '{{.State.Health.Status}}' hermes-webui
curl -s -o /dev/null -w '%{http_code}\n' http://100.64.0.100:8788/health # 200
curl -s -o /dev/null -w '%{http_code}\n' http://100.64.0.100:8788/ # 302 -> /login
Keep the vendored agent version aligned with the fleet image (both 0.21.1) — the init log lines above prove which config file it reads.
Backups¶
- The fleet home (
/opt/homelab-data/hermes) holds everything precious (sessions, memory, profiles, auth.json, webui attachments) and rides the Backrest data plans (03:30 pi-hdd / 04:30 gdrive). - The stack dir
/opt/docker/hermes-webuirides the config plans; onlyworkspace/and.envare ours there —src/+hermes-agent/are reproducible vendor copies. - The webui's own state dir (
state/webui: theme, UI prefs) is container-local and resets on recreate — by design, nothing precious. - A full restore is: restore the fleet home (data repo) + the stack dir
(config repo),
docker compose up -d.
Troubleshooting¶
- Container unhealthy but serving — the image-default healthcheck probes
localhost:8787, wrong for this host-net + mesh-IP deployment (port 8788). The compose overrides it (health_probe.sh 100.64.0.100 8788); if you ever see permanent unhealthy + working UI, the override was lost in an edit. - 401 on everything from scripts — password auth is on; scripts must use
the session cookie from
/login, not basic auth. - "Agent features may not work correctly" at startup — the vendored
agent's deps failed to install; check
HERMES_WEBUI_AUTO_INSTALL=1is set and thehermes-agent/dir is a complete source tree, then recreate. - Profiles/sessions panels empty — the webui is not reading the fleet
home; verify the
/opt/homelab-data/hermes:/home/hermeswebui/.hermesmount exists and the startup log names a fleet profile config file. - Port collision — 8787 is termix's; this stack is deliberately on 8788. Don't "fix" it back to the upstream default.