hermes - 💡(How to fix) Fix Docker on Windows: API server off by default, missing port mapping, undocumented env vars, and fragile dashboard/workspace recreation

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Running the Docker stack from docker-compose.yml + docker-compose.windows.yml on Windows 11 / Docker Desktop 4.76 leaves Hermes Desktop stuck on CONNECTING because the gateway's HTTP API server is not enabled and not port-mapped by the shipped Windows override. Across debugging this and previous incidents I hit several related issues that together make the Docker path on Windows quite fragile and largely undocumented. Filing them as a single issue so the team can split / triage; happy to break out into separate issues if preferred.

Versions:

  • hermes-agent engine v0.15.1 (commit 9272e40, build 2026-06-03)
  • Hermes Desktop bundle from hermes-assets.nousresearch.com/Hermes-Setup.exe
  • Docker Desktop 4.76.0, Windows 11 23H2

Error Message

This makes scripted setup (CI, fleet deployment, migration from one machine to another, post-reinstall scripts) effectively impossible without driving the GUI. The error message also lies: a token is saved, it's just in an encoding the validator rejects. ERROR gateway.platforms.api_server: [Api_Server] Port 8642 already in use.

Root Cause

Running the Docker stack from docker-compose.yml + docker-compose.windows.yml on Windows 11 / Docker Desktop 4.76 leaves Hermes Desktop stuck on CONNECTING because the gateway's HTTP API server is not enabled and not port-mapped by the shipped Windows override. Across debugging this and previous incidents I hit several related issues that together make the Docker path on Windows quite fragile and largely undocumented. Filing them as a single issue so the team can split / triage; happy to break out into separate issues if preferred.

Fix Action

Fix / Workaround

Workaround: docker restart hermes from the host. The UI button is currently unsafe.

  • OS: Windows 11 23H2 (build 22631)
  • Docker Desktop 4.76.0
  • Hermes engine v0.15.1 commit 9272e40
  • Hermes Desktop installed via Hermes-Setup.exe from hermes-assets.nousresearch.com
  • Python 3.11 in %LOCALAPPDATA%\hermes\hermes-agent\venv\ (used in mode: local)
  • Workaround in use: switched back to mode: local (native Windows venv) — works reliably and avoids issues 1, 2, 3, 4, 5 entirely.

Code Example

WARNING gateway.run: No messaging platforms enabled.
┌─────────────────────────────────────────┐
│   ⚕ Hermes Gateway Starting...Messaging platforms + cron scheduler  │
└─────────────────────────────────────────┘

---

# Required addition that's missing from docker-compose.windows.yml
services:
  gateway:
    network_mode: bridge   # main compose has host mode — Compose merge doesn't drop it
    ports:
      - "127.0.0.1:8642:8642"

---

[hermes] [boot] Desktop boot failed: Remote Hermes gateway is selected, but no session token is saved.
                Open SettingsGateway and save a token, or switch back to Local.

---

ERROR gateway.platforms.api_server: [Api_Server] Port 8642 already in use.
INFO gateway.run: Reconnect api_server failed, next retry in 60s ... 120s ... 240s

---

docker restart hermes
docker restart hermes-dashboard          # NOT compose up -d dashboard — see below
docker restart hermes-workspace

---

docker.EXE run -d --init --name hermes-<hex> ... \
  -w 'C:\Users\<username>' ... \
  -v ... nikolaik/python-nodejs:python3.11-nodejs20 sleep infinity
RAW_BUFFERClick to expand / collapse

Summary

Running the Docker stack from docker-compose.yml + docker-compose.windows.yml on Windows 11 / Docker Desktop 4.76 leaves Hermes Desktop stuck on CONNECTING because the gateway's HTTP API server is not enabled and not port-mapped by the shipped Windows override. Across debugging this and previous incidents I hit several related issues that together make the Docker path on Windows quite fragile and largely undocumented. Filing them as a single issue so the team can split / triage; happy to break out into separate issues if preferred.

Versions:

  • hermes-agent engine v0.15.1 (commit 9272e40, build 2026-06-03)
  • Hermes Desktop bundle from hermes-assets.nousresearch.com/Hermes-Setup.exe
  • Docker Desktop 4.76.0, Windows 11 23H2

1. Gateway HTTP API server is OFF by default — and the .env.example does not mention the variables that enable it

docker compose ... up -d brings the container up, hermes status says "Gateway Service: ✓ running", but nothing listens on 8642. The gateway only starts the messaging + cron scheduler path:

WARNING gateway.run: No messaging platforms enabled.
┌─────────────────────────────────────────┐
│   ⚕ Hermes Gateway Starting...         │
│   Messaging platforms + cron scheduler  │
└─────────────────────────────────────────┘

The HTTP API platform is gated behind these env vars (see gateway/config.py / gateway/platforms/api_server.py):

  • API_SERVER_ENABLED=true
  • API_SERVER_KEY=<token> (required)
  • API_SERVER_HOST=0.0.0.0 (else only 127.0.0.1 inside the container)
  • API_SERVER_PORT=8642 (default)

grep -E 'API_SERVER|8642' .env.example in 9272e40 returns zero hits. The only mention of these vars is a comment block inside docker-compose.yml that says "uncomment API_SERVER_KEY and API_SERVER_HOST" — but API_SERVER_ENABLED is missing from that block too, and API_SERVER_PORT is undocumented anywhere outside the source.

Repro:

  1. Clean clone, docker compose -f docker-compose.yml -f docker-compose.windows.yml up -d.
  2. From host: curl http://127.0.0.1:8642/v1/models → connection refused.
  3. From inside: cat /proc/net/tcp | awk '$2 ~ /:21C2$/' → empty (port 8642 not bound).

Suggested fix: document API_SERVER_* in .env.example, and either flip default to enabled=true when a key is present, or print a clearer hint at boot ("API HTTP server disabled — set API_SERVER_ENABLED=true + API_SERVER_KEY to expose 8642").


2. docker-compose.windows.yml does not publish port 8642 even when the API is enabled

The shipped Windows override removes network_mode: host (correct, it isn't supported on Docker Desktop Windows) and adds an explicit ports: mapping for the dashboard (9119), but not for the gateway HTTP API (8642). So even if the user manages to enable API_SERVER_ENABLED=true through their own .env, the port stays unreachable from Windows host until they write their own override:

# Required addition that's missing from docker-compose.windows.yml
services:
  gateway:
    network_mode: bridge   # main compose has host mode — Compose merge doesn't drop it
    ports:
      - "127.0.0.1:8642:8642"

Without network_mode: bridge explicitly in the override, Compose merges host from the base file and prints:

gateway Published ports are discarded when using host network mode

…silently ignoring the ports: you may have added.

Suggested fix: in docker-compose.windows.yml, set network_mode: bridge explicitly on gateway and publish the documented HTTP/WS ports. Add a short note: "Compose merge does not strip network_mode — bridge must be set explicitly."


3. Hermes Desktop connection.json only accepts encoding: "safeStorage" — no programmatic seeding path

%APPDATA%\Hermes\connection.json is the canonical place where the Desktop stores { mode, remote.url, remote.token }. The token is required when mode: "remote", and the Desktop's validator only treats the token as "saved" when encoding == "safeStorage" (Electron safeStorage, DPAPI-encrypted on Windows). Writing encoding: "plain" with the raw token is silently ignored — the boot loop logs:

[hermes] [boot] Desktop boot failed: Remote Hermes gateway is selected, but no session token is saved.
                Open Settings → Gateway and save a token, or switch back to Local.

This makes scripted setup (CI, fleet deployment, migration from one machine to another, post-reinstall scripts) effectively impossible without driving the GUI. The error message also lies: a token is saved, it's just in an encoding the validator rejects.

Suggested fix: either (a) accept encoding: "plain" with a one-time warning and migrate it to safeStorage on next save, or (b) expose hermes desktop set-remote --url ... --token ... that performs the safeStorage write headlessly.


4. "Restart Gateway" button in the dashboard sidebar leaves gateway_state.json corrupt (still relevant in v0.15.1)

Clicking Restart Gateway in the dashboard sidebar runs hermes gateway restart, which does not kill the old daemon before starting a new one. The new instance fails immediately:

ERROR gateway.platforms.api_server: [Api_Server] Port 8642 already in use.
INFO gateway.run: Reconnect api_server failed, next retry in 60s ... 120s ... 240s

Meanwhile the old PID keeps serving 8642 correctly, but /opt/data/gateway_state.json is overwritten with the failing PID and platforms.api_server.state: "retrying". The sidebar reads this state and reports Gateway Status: Stopped even though /health returns 200.

Workaround: docker restart hermes from the host. The UI button is currently unsafe.

Suggested fix: hermes gateway restart should stop (waiting for port release) before start, and on failure should leave the previous valid gateway_state.json intact.


5. Recreation order matters and is undocumented

hermes-dashboard uses network_mode: service:gateway. Recreating gateway (which docker compose up -d --force-recreate gateway does freely) leaves the dashboard container with a stale net namespace and the workspace pointing at a dashboard URL that no longer responds. Recovery requires this exact order:

docker restart hermes
docker restart hermes-dashboard          # NOT compose up -d dashboard — see below
docker restart hermes-workspace

Gotcha: docker compose -f docker-compose.windows.yml up -d dashboard does not recreate the dashboard if its container is still Up even when its HTTP listener is dead (curl :9119 → 000). Compose checks container state, not service health. docker restart hermes-dashboard is the only reliable path.

Suggested fix: document the dependency, add a healthcheck on the dashboard so Compose treats a dead listener as a recreate trigger, or make the dashboard tolerate gateway restarts (re-resolve / retry the shared netns).


6. terminal.backend: docker is broken on Windows-native installs

Setting terminal.backend: docker in config.yaml causes Hermes to build an invalid docker run command that mixes Windows host paths into a Linux container:

docker.EXE run -d --init --name hermes-<hex> ... \
  -w 'C:\Users\<username>' ... \
  -v ... nikolaik/python-nodejs:python3.11-nodejs20 sleep infinity

Exits 125. Root cause: tools/terminal_tool.py _get_env_config() around line 1037 reads TERMINAL_ENV from os.getenv only (ignores config.yaml), then default_cwd = os.getcwd() (= the Windows user profile because the Tauri wrapper inherits the user's cwd). That cwd is then injected as -w in tools/environments/docker.py around line 851.

Things tried, all unsuccessful:

  • docker_mount_cwd_to_workspace: false + cwd: /workspace in config.yaml → no effect on -w.
  • docker_extra_args: ["-w", "/workspace"] → ignored by the command constructor.
  • TERMINAL_ENV=docker in .env (HERMES_HOME) → doesn't propagate to the subprocess.

Suggested fix: in _get_env_config(), read from config.yaml first, env second; in docker.py, translate Windows cwds (or fall back to /workspace) before passing to -w.


7. Auth.json caching in Docker volume (acknowledged; partially mitigated by #21880)

Mentioning for completeness — hermes reads /opt/data/auth.json from the named volume before reading env vars, so updating provider keys in the host .env does not take effect until you also delete or rewrite auth.json inside the volume. PR #21880 bootstraps auth.json from env on first boot, which helps fresh installs but does nothing for upgraded / re-keyed installations. Worth a short note in the docs.


Environment

  • OS: Windows 11 23H2 (build 22631)
  • Docker Desktop 4.76.0
  • Hermes engine v0.15.1 commit 9272e40
  • Hermes Desktop installed via Hermes-Setup.exe from hermes-assets.nousresearch.com
  • Python 3.11 in %LOCALAPPDATA%\hermes\hermes-agent\venv\ (used in mode: local)
  • Workaround in use: switched back to mode: local (native Windows venv) — works reliably and avoids issues 1, 2, 3, 4, 5 entirely.

Happy to provide additional logs (gateway, dashboard, desktop boot), strace-equivalent of the docker backend invocation, or test any proposed fix. Issues 1–3 are the highest-impact for new Windows users; the others are quality-of-life / robustness.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING