From 845aa60f66512259b05e516fdc4d9090b23b40f7 Mon Sep 17 00:00:00 2001 From: Rod Boev Date: Wed, 10 Jun 2026 15:08:53 -0400 Subject: [PATCH] docs(#3733): document three-service unified setup and warn about dashboard write conflicts (#3938) Co-authored-by: nesquena-hermes --- docs/docker.md | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/docs/docker.md b/docs/docker.md index cc7d96a8..69a6cfa8 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -11,6 +11,14 @@ This is the comprehensive Docker reference. For a 5-minute quickstart, see the [ | **Three-container** | Two-container PLUS the dashboard for monitoring. | `docker-compose.three-container.yml` | | **All-in-one image** (community fork — third-party, not maintained by us) | Podman 3.4 / multi-arch / supervisord-style preference. | [sunnysktsang/hermes-suite](https://github.com/sunnysktsang/hermes-suite) — see [#1399](https://github.com/nesquena/hermes-webui/issues/1399) for the original discussion | +> **Note (v0.14+):** If you use `docker-compose.three-container.yml`, both +> `hermes-agent` and `hermes-dashboard` initialise from the same image and write +> to the same `hermes-home` volume simultaneously. This can cause overlapping lock +> files and stale `gateway_state.json` entries. The unified pattern described in +> [Three-service unified setup (v0.14+)](#three-service-unified-setup-v014) below +> avoids this by running a single `hermes-agent` process that serves both the +> gateway and the dashboard. + If something stops working, **start with the single-container setup** — it's the simplest path and fixes most permission/UID/path-mismatch issues by construction. ## Production image security model @@ -174,6 +182,87 @@ For container-to-container diagnostics, set one of `HERMES_API_URL` or `HERMES_W Refs #2785. +## Three-service unified setup (v0.14+) + +Since v0.14, `hermes-agent` can serve the gateway API and the built-in dashboard +from the same process by setting `HERMES_DASHBOARD_HOST` and +`HERMES_DASHBOARD_PORT`. Running agent and dashboard in one container means a +single writer to `hermes-home`, eliminating the concurrent-init write conflicts +that occur when `hermes-agent` and `hermes-dashboard` both start from the same +image against the same volume. + +The three-service pattern uses two containers: + +| Service | Image | Ports | +|---|---|---| +| `hermes-agent` | `nousresearch/hermes-agent:latest` | 8642 (gateway), 9119 (dashboard) | +| `hermes-webui` | `ghcr.io/nesquena/hermes-webui:latest` | 8787 (chat UI) | + +Example compose snippet (save as `docker-compose.three-service.yml` or inline into your own file): + +```yaml +services: + hermes-agent: + image: nousresearch/hermes-agent:latest + container_name: hermes-agent + command: gateway run + ports: + - "127.0.0.1:8642:8642" + - "127.0.0.1:9119:9119" + volumes: + - hermes-home:/home/hermes/.hermes + - hermes-agent-src:/opt/hermes + environment: + - HERMES_HOME=/home/hermes/.hermes + - HERMES_UID=${UID:-1000} + - HERMES_GID=${GID:-1000} + - HERMES_DASHBOARD_HOST=0.0.0.0 + - HERMES_DASHBOARD_PORT=9119 + restart: unless-stopped + networks: + - hermes-net + + hermes-webui: + image: ghcr.io/nesquena/hermes-webui:latest + container_name: hermes-webui + depends_on: + - hermes-agent + ports: + - "127.0.0.1:8787:8787" + volumes: + - hermes-home:/home/hermeswebui/.hermes + - hermes-agent-src:/home/hermeswebui/.hermes/hermes-agent:ro + - ${HERMES_WORKSPACE:-${HOME}/workspace}:/workspace + environment: + - HERMES_WEBUI_HOST=0.0.0.0 + - HERMES_WEBUI_PORT=8787 + - HERMES_WEBUI_STATE_DIR=/home/hermeswebui/.hermes/webui + - WANTED_UID=${UID:-1000} + - WANTED_GID=${GID:-1000} + restart: unless-stopped + networks: + - hermes-net + +networks: + hermes-net: + driver: bridge + +volumes: + hermes-home: + hermes-agent-src: +``` + +Open http://localhost:8787 for chat and http://localhost:9119 for the dashboard. +Check `hermes gateway run --help` for the exact flag names for your agent release — +the env-var equivalents shown above (`HERMES_DASHBOARD_HOST`, `HERMES_DASHBOARD_PORT`) +are available in recent releases alongside the CLI flags. + +If you need the separate dashboard container (e.g. resource limits per service), +`docker-compose.three-container.yml` still works. Add a `depends_on` from +`hermes-dashboard` to `hermes-agent` with a `condition: service_healthy` healthcheck +so the dashboard waits for the gateway to finish initialising agent-home before it +starts its own init pass. + ## What goes wrong (and how to fix it) ### Compatibility policy and version pinning