From adc2856ffbb61444bb1f9eb9de92528f2336cd33 Mon Sep 17 00:00:00 2001 From: Ben Barclay Date: Tue, 28 Apr 2026 08:20:01 +1000 Subject: [PATCH] docs(docker): add "Multi-profile support" section Clarifies that Hermes' built-in multi-profile feature is not recommended when running under Docker. Recommends instead running one container per profile, each bind-mounting its own host data directory as /opt/data. Includes docker run examples, a rationale list (isolation, independent lifecycle, port separation, concurrent-write safety), and a Compose snippet showing two profile services side by side. --- website/docs/user-guide/docker.md | 67 ++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/website/docs/user-guide/docker.md b/website/docs/user-guide/docker.md index bdd81056ce..473cc7cc6c 100644 --- a/website/docs/user-guide/docker.md +++ b/website/docs/user-guide/docker.md @@ -105,6 +105,63 @@ The `/opt/data` volume is the single source of truth for all Hermes state. It ma Never run two Hermes **gateway** containers against the same data directory simultaneously — session files and memory stores are not designed for concurrent write access. Running a dashboard container alongside the gateway is safe since the dashboard only reads data. ::: +## Multi-profile support + +Hermes supports [multiple profiles](../reference/profile-commands.md) — separate `~/.hermes/` directories that let you run independent agents (different SOUL, skills, memory, sessions, credentials) from a single installation. **When running under Docker, using Hermes' built-in multi-profile feature is not recommended.** + +Instead, the recommended pattern is **one container per profile**, with each container bind-mounting its own host directory as `/opt/data`: + +```sh +# Work profile +docker run -d \ + --name hermes-work \ + --restart unless-stopped \ + -v ~/.hermes-work:/opt/data \ + -p 8642:8642 \ + nousresearch/hermes-agent gateway run + +# Personal profile +docker run -d \ + --name hermes-personal \ + --restart unless-stopped \ + -v ~/.hermes-personal:/opt/data \ + -p 8643:8642 \ + nousresearch/hermes-agent gateway run +``` + +Why separate containers over profiles in Docker: + +- **Isolation** — each container has its own filesystem, process table, and resource limits. A crash, dependency change, or runaway session in one profile can't affect another. +- **Independent lifecycle** — upgrade, restart, pause, or roll back each agent separately (`docker restart hermes-work` leaves `hermes-personal` untouched). +- **Clean port and network separation** — each gateway binds its own host port; there's no risk of cross-talk between chat platforms or API servers. +- **Simpler mental model** — the container *is* the profile. Backups, migrations, and permissions all follow the bind-mounted directory, with no extra `--profile` flags to remember. +- **Avoids concurrent-write risk** — the warning above about never running two gateways against the same data directory still applies to profiles within a single container. + +In Docker Compose, this just means declaring one service per profile with distinct `container_name`, `volumes`, and `ports`: + +```yaml +services: + hermes-work: + image: nousresearch/hermes-agent:latest + container_name: hermes-work + restart: unless-stopped + command: gateway run + ports: + - "8642:8642" + volumes: + - ~/.hermes-work:/opt/data + + hermes-personal: + image: nousresearch/hermes-agent:latest + container_name: hermes-personal + restart: unless-stopped + command: gateway run + ports: + - "8643:8642" + volumes: + - ~/.hermes-personal:/opt/data +``` + ## Environment variable forwarding API keys are read from `/opt/data/.env` inside the container. You can also pass environment variables directly: @@ -112,8 +169,8 @@ API keys are read from `/opt/data/.env` inside the container. You can also pass ```sh docker run -it --rm \ -v ~/.hermes:/opt/data \ - -e ANTHROPIC_API_KEY="sk-ant-..." \ - -e OPENAI_API_KEY="sk-..." \ + -e ANTHROPIC_API_KEY="***" \ + -e OPENAI_API_KEY="***" \ nousresearch/hermes-agent ``` @@ -138,9 +195,9 @@ services: - hermes-net # Uncomment to forward specific env vars instead of using .env file: # environment: - # - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - # - OPENAI_API_KEY=${OPENAI_API_KEY} - # - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN} + # - ANTHROPIC_API_KEY=${ANTH...KEY} + # - OPENAI_API_KEY=*** + # - TELEGRAM_BOT_TOKEN=${TELE...KEN} deploy: resources: limits: