Skip to content

fix(docker): align compose examples with single-container dashboard pattern#36235

Open
hulet wants to merge 1 commit into
NousResearch:mainfrom
hulet:fix/update-docker-compose-for-5671059f6
Open

fix(docker): align compose examples with single-container dashboard pattern#36235
hulet wants to merge 1 commit into
NousResearch:mainfrom
hulet:fix/update-docker-compose-for-5671059f6

Conversation

@hulet

@hulet hulet commented Jun 1, 2026

Copy link
Copy Markdown

What

Updates docker-compose.yml and docker-compose.windows.yml to use the single-container dashboard pattern that commit 5671059f6 introduced and the user-guide docs already document. Also fixes a broken image: tag in docker-compose.yml.

Why

Commit 5671059 ("feat(docker): launch dashboard as side-process via HERMES_DASHBOARD=1") explicitly said in its message:

  • Rewrite the "Running the dashboard" doc section around the new single-container pattern. Drops the previously-documented dashboard-as-its-own-container setup — that pattern relied on the deprecated env vars for cross-container gateway-liveness detection, and without them the dashboard would permanently report the gateway as "not running".
  • Collapse the two-service Compose example (gateway + dashboard container) into a single service with HERMES_DASHBOARD=1. Removes the now-unnecessary bridge network and depends_on.

The docs, entrypoint script, and s6-rc.d/dashboard/run supervisor were updated in that commit, but docker-compose.yml and docker-compose.windows.yml were not. The compose files still ship a separate dashboard container — contradicting the user-guide statement at website/docs/user-guide/docker.md (still in main):

Running the dashboard as a separate container is not supported: its gateway-liveness detection requires a shared PID namespace with the gateway process.

This PR finishes the collapse the original commit message promised.

Changes

  • Removes the standalone dashboard: service from both files (no more bridge network, no more depends_on).
  • Renames the remaining service from gatewayhermes to match the canonical compose example in website/docs/user-guide/docker.md.
  • Adds HERMES_DASHBOARD=1 to launch the supervised dashboard as a sibling s6 service inside the same container.
  • Linux (docker-compose.yml): keeps the dashboard bound to 127.0.0.1 via HERMES_DASHBOARD_HOST so the loopback-only behavior of the old separate dashboard service is preserved (under network_mode: host, container loopback == host loopback).
  • Windows (docker-compose.windows.yml): keeps the old --insecure intent via HERMES_DASHBOARD_INSECURE=1. The default in-container bind is 0.0.0.0; without this opt-out the dashboard would fail closed at startup since no DashboardAuthProvider is registered. The existing 127.0.0.1:9119:9119 port mapping restricts the published port to host loopback.
  • Fixes the local-build image tag in docker-compose.yml from the unprefixed hermes-agent to nousresearch/hermes-agent, matching the published image name so the example file works as-is.
  • --no-open is now hardcoded in docker/s6-rc.d/dashboard/run, so it no longer needs to appear on the compose command line.

How to test

Linux / docker-compose.yml:

HERMES_UID=$(id -u) HERMES_GID=$(id -g) docker compose up -d
docker compose logs -f hermes        # see the gateway + supervised dashboard come up
curl -sf http://127.0.0.1:9119/ >/dev/null && echo "dashboard reachable on loopback"
docker compose exec hermes /opt/hermes/.venv/bin/hermes gateway status

Windows / docker-compose.windows.yml:

docker compose -f docker-compose.windows.yml up -d
# Dashboard reachable at http://127.0.0.1:9119 (loopback only, due to the port mapping)

What I tested on

Tested on a Debian Linux homelab host. I ran the updated docker-compose.yml as-is using the pulled nousresearch/hermes-agent image. The supervised dashboard came up on 127.0.0.1:9119 and reported the gateway as running.

docker-compose.windows.yml not tested directly (no Windows host available); the diff is the structural mirror of the Linux change minus network_mode: host plus the existing port mapping.

Related issues

Possibly closes or reduces noise on several open issues that look like downstream consequences of users copying the stale two-service example:

…attern

Commit 5671059 ("feat(docker): launch dashboard as side-process via
HERMES_DASHBOARD=1") collapsed the documented dashboard deployment
model into a single container — its message reads:

  - Rewrite the "Running the dashboard" doc section around the new
    single-container pattern.  Drops the previously-documented
    dashboard-as-its-own-container setup — that pattern relied on the
    deprecated env vars for cross-container gateway-liveness detection,
    and without them the dashboard would permanently report the gateway
    as "not running".
  - Collapse the two-service Compose example (gateway + dashboard
    container) into a single service with HERMES_DASHBOARD=1.  Removes
    the now-unnecessary bridge network and `depends_on`.

The docs and entrypoint were updated, but docker-compose.yml and
docker-compose.windows.yml were not. The user-guide docker page now
states: "Running the dashboard as a separate container is not supported:
its gateway-liveness detection requires a shared PID namespace with
the gateway process." Both example compose files still ship a separate
dashboard container, contradicting that.

This finishes the collapse the original commit message promised:
  - Removes the standalone dashboard service from both files
  - Renames the remaining service from `gateway` to `hermes`, matching
    the canonical compose example shown in
    website/docs/user-guide/docker.md
  - Adds HERMES_DASHBOARD=1 to launch the supervised dashboard sibling
  - Linux: keeps the dashboard bound to 127.0.0.1 via
    HERMES_DASHBOARD_HOST to preserve the old loopback-only behavior
  - Windows: keeps the old `--insecure` opt-out via
    HERMES_DASHBOARD_INSECURE=1 so the dashboard doesn't fail closed
    at startup with the default 0.0.0.0 in-container bind
  - Fixes the local-build image tag in docker-compose.yml from the
    untagged `hermes-agent` to `nousresearch/hermes-agent`, matching
    the published image name so the example file actually works as-is
  - `--no-open` is now hardcoded in docker/s6-rc.d/dashboard/run, so
    it no longer needs to be on the compose command line

Likely closes / reduces noise on several open issues that look like
downstream consequences of users copying the stale two-service example:
  - NousResearch#26181 (dashboard reports gateway 'stopped' on Docker / PID-1)
  - NousResearch#34457, NousResearch#34480 (s6-log lock collision in multi-container setups
    with shared /opt/data)
  - NousResearch#23402 (HERMES_UID permissions issue with the separate dashboard)
  - NousResearch#20739 (dashboard chat unusable in Docker — four compounding bugs)

Tested on a Debian Linux homelab host running the resulting
docker-compose.yml against a fresh build of the image; the supervised
dashboard came up on 127.0.0.1:9119 with the gateway visible as
running. Windows variant not tested (no Windows host); the diff is the
mirror of the Linux change minus network_mode: host plus the existing
127.0.0.1:9119:9119 port mapping.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docker Docker image, Compose, packaging backend/docker Docker container execution P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants