Files
2026-07-12 10:17:17 -04:00

9.5 KiB

name, description, version, author, license, platforms, metadata, related_skills
name description version author license platforms metadata related_skills
hermes-webui Deploy, configure, and troubleshoot the Hermes Web UI Docker container — the browser interface for Hermes Agent. 1.0.0 Hermes Agent MIT
linux
macos
hermes
tags source
hermes
webui
docker
browser
troubleshooting
https://github.com/nesquena/hermes-webui
hermes-agent
hermes-dashboard

Hermes Web UI

The Hermes Web UI (ghcr.io/nesquena/hermes-webui) provides a browser-based interface for Hermes Agent — chat with the agent, browse sessions, manage workspace files, and monitor agent activity. It runs as a Docker container alongside the Hermes Agent gateway.

For a management-focused control panel (config editing, model switching, tool toggling, cron control, log viewing), see the hermes-dashboard skill — a complementary Flask dashboard that reads Hermes state directly from the filesystem.

Quick Start

# Pull and run
docker run -d \
  --name hermes-webui \
  -p 8787:8787 \
  -v /path/to/hermes-home:/home/hermeswebui/.hermes \
  -v /path/to/workspace:/workspace \
  -e HERMES_WEBUI_PASSWORD=your-password \
  ghcr.io/nesquena/hermes-webui:latest

# With agent source mounted (for full functionality):
docker run -d \
  --name hermes-webui \
  -p 8787:8787 \
  -v /path/to/hermes-home:/home/hermeswebui/.hermes:ro \
  -v /path/to/hermes-agent-source:/home/hermeswebui/.hermes/hermes-agent:ro \
  -v /path/to/workspace:/workspace \
  -e HERMES_WEBUI_PASSWORD=your-password \
  ghcr.io/nesquena/hermes-webui:latest

Open http://localhost:8787 in a browser and log in with the password.

Architecture

The Web UI requires two adjacent systems to function fully:

  1. Hermes Agent source code — the Web UI imports AIAgent from the Hermes Agent Python library directly. Without it, features like model auto-detection, personality routing, and CLI session imports are disabled.
  2. Hermes Gateway / API Server — the Web UI communicates with the Hermes API server (OpenAI-compatible, typically port 8642) for agent execution. The API server is started by the Hermes gateway process.

Configuration

Environment Variables

Variable Default Description
HERMES_WEBUI_PASSWORD (required) Login password for the web interface
HERMES_WEBUI_BIND_HOST 0.0.0.0 IP to bind the HTTP server
HERMES_WEBUI_BIND_PORT 8787 Port for the HTTP server
HERMES_WEBUI_STATE_DIR ~/.hermes/webui Where sessions, workspaces, and state are stored
HERMES_WEBUI_DEFAULT_WORKSPACE /workspace Default workspace directory shown on first launch
WANTED_UID 1024 User ID to run as (auto-detected from mounted volumes)
WANTED_GID 1024 Group ID (auto-detected from mounted volumes)

Volume Mounts

Host Path Container Path Purpose
~/.hermes /home/hermeswebui/.hermes Hermes home directory (config, sessions, skills)
~/.hermes/hermes-agent /home/hermeswebui/.hermes/hermes-agent Agent source code (for AIAgent import)
/path/to/workspace /workspace Workspace/project files

Common Tasks

Check if agent is recognized

docker logs hermes-webui | grep -E "agent dir|AIAgent"

Expected healthy output:

  agent dir   : /home/hermeswebui/.hermes/hermes-agent  [ok]

Verify health

curl -s http://localhost:8787/health

View server logs

docker logs hermes-webui

Restart

docker restart hermes-webui

Pitfalls

  • HERMES_WEBUI_STATE_DIR is required. Despite having a default in the docs, the container errors out hard without it: !! ERROR: HERMES_WEBUI_STATE_DIR not set. Always pass -e HERMES_WEBUI_STATE_DIR=/home/hermeswebui/.hermes/webui on the docker run command, or the container will crash-loop.
  • Agent source must be accessible at container startup. The init script installs dependencies from pyproject.toml before the server starts. If the source is added after the container is already running, you must remove /app/venv/.deps_installed and restart for the init script to reinstall.
  • Read-only mounts recommended. The init script warns if the agent source mount is writable from the WebUI container. The multi-container compose defaults use a read-only mount for defence-in-depth.
  • Password redaction in terminal output. When constructing the docker run command through the terminal tool, the password in -e HERMES_WEBUI_PASSWORD=secret may be replaced with *** by secret redaction before the command executes. To bypass: use execute_code with Python to construct the command, or write the password hex-encoded and decode it in the heredoc, or verify the deployed password by checking its length and first/last chars via docker inspect.
  • Permission errors on restart. Prior pip install -e runs as root may leave root-owned .pyc files in the venv. If the init script errors with Permission denied during reinstall, clean them: docker exec hermes-webui find /app/venv -user root -delete
  • First startup is slow. The init script installs dependencies on first run — allow ~30 seconds for startup.
  • API server must be running. The Web UI needs the Hermes API server (started by hermes gateway run) on port 8642. Without it, agent chat will fail even if the Web UI's health endpoint reports OK.
  • Provider credential mismatch. The Web UI has its OWN isolated .env and config.yaml inside the mounted Hermes home directory, separate from the host's Hermes config. If these files use a different provider or a placeholder API key, the agent will fail with HTTP 401 errors. Always sync both files when switching providers. See references/provider-credentials-and-sessions.md.
  • Stale sessions retain old provider settings. Sessions are cached in <state_dir>/sessions/<id>.json with the model and provider that were active at creation time. Switching providers in config.yaml does NOT update existing sessions. The web UI reads s.model and s.model_provider from the cached session and passes them to AIAgent.__init__, which then tries the OLD provider. Symptoms: "No LLM provider configured" on messages even after a correct provider config. Fix: update both model and model_provider fields in the session JSON, or delete the session file so the frontend creates a fresh one.
  • settings.json caches default_model_provider. The file at <state_dir>/settings.json stores default_model_provider. If you switched providers, update this field too — otherwise new sessions will still be created with the old provider.

Troubleshooting

Symptom: HTTP 401 on chat

Check the web UI's .env has the correct API key for the provider in config.yaml:

# Compare config provider with available keys
docker exec hermes-webui cat /home/hermeswebui/.hermes/config.yaml
docker exec hermes-webui cat /home/hermeswebui/.hermes/.env

The key variable name must match what the provider expects (e.g. DEEPSEEK_API_KEY for deepseek, OPENROUTER_API_KEY for openrouter).

Symptom: "No LLM provider configured" on every message

This usually means the cached session has a stale provider. Check and fix:

# 1. Check what model/provider the session has
docker exec hermes-webui bash -c 'python3 -c "
import json
with open(\"/home/hermeswebui/.hermes/webui/sessions/$(
  ls -t /home/hermeswebui/.hermes/webui/sessions/*.json 2>/dev/null | head -1
  )\") as f:
    d = json.load(f)
    print(f\"model={d.get(\\\"model\\\")}  provider={d.get(\\\"model_provider\\\")}\")
"'

# 2. Fix the session (replace with your actual provider/model)
docker exec hermes-webui bash -c 'python3 -c "
import json
p = \"/home/hermeswebui/.hermes/webui/sessions/*.json\"
import glob
for f in glob.glob(p):
    with open(f) as fh:
        d = json.load(fh)
    d[\"model\"] = \"deepseek-v4-flash\"
    d[\"model_provider\"] = \"deepseek\"
    with open(f, \"w\") as fh:
        json.dump(d, fh)
"'

# 3. Also fix settings.json if needed
docker exec hermes-webui bash -c 'python3 -c "
import json
with open(\"/home/hermeswebui/.hermes/webui/settings.json\") as f:
    d = json.load(f)
d[\"default_model_provider\"] = \"deepseek\"
with open(\"/home/hermeswebui/.hermes/webui/settings.json\", \"w\") as f:
    json.dump(d, f, indent=2)
"'

# 4. Restart to pick up changes
docker restart hermes-webui

Alternatively, delete the stale session entirely and let the frontend create a fresh one:

docker exec hermes-webui bash -c 'rm -f /home/hermeswebui/.hermes/webui/sessions/*.json && echo "{}" > /home/hermeswebui/.hermes/webui/sessions/_index.json'
docker restart hermes-webui

Symptom: Provider shows as configured but models fail to load

Check that the web UI's config.yaml uses the correct key names for the model section:

model:
  provider: deepseek          # Must match a provider in the Hermes registry
  default: deepseek-v4-flash  # The model name
  base_url: https://api.deepseek.com/v1

The config.yaml key is default (not model). If you wrote model: inside the model: section, provider resolution will return empty.

References

  • references/aiagent-not-available.md — fixing the "AIAgent not available" error when the container cannot find the Hermes Agent source.
  • references/provider-credentials-and-sessions.md — detailed diagnosis flow for 401 errors and stale session/provider mismatches, including scripted fixes.
  • references/firecrawl-reddit-limitations.md — Firecrawl explicitly blocks Reddit; only WSB RSS works.