docs(docker): document agent-image upgrade flow + read-only WebUI source mount

The hermes-agent-src named volume in the two- and three-container compose
files is initialised from the agent image's /opt/hermes on first `up` and
Docker reuses it verbatim on every subsequent `up` — even after a fresh
`docker pull` of the agent image. This was the root cause of #1416 (the
'missing entrypoint' symptom was a stale cached volume hiding the new
image's source tree).

Changes:

- Add an 'Upgrading the agent container' section to docs/docker.md with
  the canonical `down → docker volume rm → pull → up -d` recipe, plus the
  same pointer as a comment block in both multi-container compose files
  near the volume declarations.
- Switch the WebUI's hermes-agent-src mount to `:ro` in both multi-container
  compose files. The WebUI only reads this volume to install the agent's
  Python deps at startup; mounting it read-only enforces that at the kernel
  layer and brings the actual mount mode in line with the existing
  docs/docker.md architecture diagram (which already labelled this edge as
  read-only).
- Align the workspace bind default in both multi-container compose files
  with the single-container convention — `${HERMES_WORKSPACE:-${HOME}/workspace}`
  instead of `${HERMES_WORKSPACE:-~/workspace}` — so the default resolves
  the same way across Linux, macOS, WSL2, and Docker Desktop on Windows.
- Add a 'What the multi-container setup isolates (and what it doesn't)'
  section to docs/docker.md to frame the two/three-container setups as
  process/network/resource isolation, not filesystem isolation, so users
  don't reach for multi-container expecting a trust boundary it doesn't
  provide.
- Cross-link #1416 from the Related issues section.

Adds 9 regression tests in tests/test_docker_docs_and_readonly.py covering:
- :ro on the WebUI side of hermes-agent-src in both files
- agent side stays read-write (still needs to populate /opt/hermes on first run)
- ${HOME} (not ~) in workspace bind defaults in both files
- single-container file already uses ${HOME} (pin to prevent drift)
- docs/docker.md has the 'Upgrading the agent container' section + recipe
- compose files reference docs/docker.md + show the upgrade step inline
- docs/docker.md frames the isolation model honestly

Test suite: 42 passed (33 existing Docker tests + 9 new). No behaviour
change for users who set HERMES_WORKSPACE explicitly, and no migration is
required for existing deployments — Docker rebinds the existing volume
read-only on next `up`. Users upgrading the agent image should now follow
the documented `docker volume rm hermes-agent-src` recipe.

Closes #1416 (documented upgrade procedure) and addresses the read-only
half of the multi-container coupling concern raised on #2453.
This commit is contained in:
nesquena-hermes committed 2026-05-17 17:18:39 +00:00
1 parent 522efc2921
commit 5cc8b6c654
5 files changed
+245 -11

No files matched your search

+19 -5
View File
@@ -109,13 +109,15 @@ services:
# Same hermes home as the agent — shares config, sessions, state
- hermes-home:/home/hermeswebui/.hermes
# Agent source mounted where docker_init.bash expects it.
# At startup the init script runs:
# uv pip install /home/hermeswebui/.hermes/hermes-agent
# which installs the agent and all its Python dependencies.
- hermes-agent-src:/home/hermeswebui/.hermes/hermes-agent
# Mounted read-only — the WebUI only reads this volume to install
# the agent's Python dependencies at startup (`uv pip install`).
# Read-only enforces that defence-in-depth at the kernel layer.
- hermes-agent-src:/home/hermeswebui/.hermes/hermes-agent:ro
# Workspace directory — browse and edit files from the WebUI.
# Adapt the host path to your project directory.
- ${HERMES_WORKSPACE:-~/workspace}:/workspace
# ${HOME} is used rather than `~` so the default resolves the same way
# across Linux, macOS, WSL2, and Docker Desktop on Windows.
- ${HERMES_WORKSPACE:-${HOME}/workspace}:/workspace
environment:
- HERMES_WEBUI_HOST=0.0.0.0
- HERMES_WEBUI_PORT=8787
@@ -150,5 +152,17 @@ networks:
driver: bridge
volumes:
# IMPORTANT — upgrading the agent image:
# The `hermes-agent-src` volume is initialised from the agent image's
# `/opt/hermes` on first `up`, and Docker reuses the volume verbatim on
# later runs — even after `docker pull` of a newer agent image. After
# upgrading the agent image, run:
#
# docker compose -f docker-compose.three-container.yml down
# docker volume rm <project>_hermes-agent-src
# docker compose -f docker-compose.three-container.yml pull
# docker compose -f docker-compose.three-container.yml up -d
#
# The full procedure (and why) is documented in docs/docker.md.
hermes-home:
hermes-agent-src: