How-To Guide
Hermes Agent Docker Compose Setup with the Official Image
Run Hermes Agent with the official Docker image, persistent /opt/data storage, supervised gateways, private dashboard access, and host or sidecar Ollama.
Quick answer
Run the official nousresearch/hermes-agent:stable image with gateway run and persistent /opt/data. Run setup once for a new data directory; no native installation is required. Host Ollama uses host.docker.internal:11434/v1 on macOS/Windows, while a Compose sidecar uses ollama:11434/v1. Keep optional dashboard/API access protected and verify the running image after each service replacement.
This guide runs Hermes itself in Docker as an always-on service. That is different from setting terminal.backend: docker, which keeps Hermes on the host and sandboxes only terminal, file, and code-execution tools. The official container keeps mutable agent state in /opt/data while the application tree under /opt/hermes stays immutable. If you have not chosen the architecture yet, use the Hermes Agent Docker vs native install guide before creating the Compose service.
$49/mo or $39/mo billed yearly · AI included · 14‑day guarantee
Before you start:
- ☑Docker Engine plus the
docker composeplugin - ☑A chosen persistent data directory or native Docker volume, with a safe migration plan if reusing existing SQLite state
- ☑Provider and gateway credentials stored in
~/.hermes/.envor a secrets manager, never baked into the image - ☑A configured authentication provider for the non-loopback dashboard listener, plus a private or properly secured host access path
- ☑Optional local inference: a running Ollama server and one pulled tool-capable model; Docker must be able to reach its
/v1/modelsendpoint
Steps
- 1
Back up state without racing active writers
For existing data, stop every CLI, gateway and dashboard process that uses the directory before a filesystem backup or database migration. Copy the complete directory to a protected backup location, preserving ownership. New users can choose a new data directory; a native Hermes install is not required. On Docker Desktop/VM bind mounts, read the official SQLite storage requirements before reusing a WAL-mode state.db. Do not delete database sidecar files.
- 2
Create and initialize the official Compose service
Use image
nousresearch/hermes-agent:stable, commandgateway run, restart policyunless-stopped, and mount your chosen directory at/opt/data. Setcontainer_name: hermesif using the docker exec examples below. On a new setup, rundocker compose run --rm hermes setupbefore starting the gateway. Never point two gateway containers at the same data directory. See the Docker installation walkthrough for first-run and running-image checks. - 3
Choose where Ollama runs
Keep Ollama on the Mac or Windows host for the simplest GPU access, or run it as an
ollamaservice on the same Compose network. Inside Docker,127.0.0.1means the Hermes container itself, not the host. - 4
Point Docker at the correct Ollama endpoint
For host Ollama on macOS or Windows, set the custom provider base URL to
http://host.docker.internal:11434/v1. For an Ollama sidecar, usehttp://ollama:11434/v1. On Linux, use a shared Docker network or deliberate host networking instead of assuming the Desktop hostname exists. - 5
Prove Ollama connectivity from inside Hermes
Run
docker exec hermes curl -s http://host.docker.internal:11434/v1/modelson macOS/Windows, or replace the host withollamafor a sidecar. Use the exact model ID returned by/v1/modelsorollama list, then run a real file-and-terminal tool test. - 6
Publish only the private ports you need
A chat-only gateway needs neither published port. If enabling the dashboard with
HERMES_DASHBOARD=1, a host-loopback mapping such as127.0.0.1:9119:9119restricts host exposure. It does not change the listener inside the container. Port 8642 is a separate optional API surface; enable and protect it only for a defined client. - 7
Configure authentication for the container listener
The dashboard normally binds to
0.0.0.0inside the container, so it requires a supported authentication provider even when the host publishes 9119 only on loopback. Configure Basic Auth, Nous OAuth or OIDC as documented; use a tunnel or trusted private network for the outer access path. Self-hosted WebUI includes PTY/WebSocket Chat, not just monitoring. - 8
Start and inspect the container
Run
docker compose up -d, thendocker compose psanddocker compose logs -f hermes. The official image uses s6 supervision to restart the gateway and dashboard processes inside the container. - 9
Run health checks inside Docker
Run
docker exec hermes hermes doctor,docker exec hermes hermes gateway status, and a smalldocker exec hermes hermes chat -q "Reply with: docker-ok"smoke test. - 10
Verify persistent state
Confirm config, sessions, memories, skills, cron jobs, hooks, and logs appear under host
~/.hermes. Recreate the container once and verify that the same state returns. - 11
Verify the real delivery path
Send a test message through the configured Telegram, Discord, Slack, or webhook channel. A healthy container is not proof that channel permissions, topics, or delivery targets work.
- 12
Replace the intended service and verify its image
Before pulling, record
docker inspect --format '{{.Config.Image}} {{.Image}}' hermesand retain the tested image plus a compatible backup. Rundocker compose pull hermes, thendocker compose up -d --no-deps --force-recreate hermes. This interrupts the Hermes service, not unrelated sidecars. Preserve/opt/dataand rerun doctor, the provider request and exact-channel reply. A successful pull alone does not update a running container.
Pro Tips
- 💡The official image maps host
~/.hermesto/opt/data; this is the persistent source of truth for config, secrets, profiles, memory, sessions, skills, cron, hooks, and logs. - 💡The application tree at
/opt/hermesis immutable in published images. Make durable changes through skills, plugins, memory, and config under/opt/data; ship core changes by updating the image. - 💡Use
docker logs -f hermesfor live output and host~/.hermes/logs/gateways/default/currentfor persistent per-profile gateway logs. - 💡One official container can supervise multiple Hermes profiles. Use separate containers only for resource, image, network, or compliance isolation.
- 💡Do not confuse full-container deployment with the Docker terminal backend. Task mounts belong to that execution boundary; the application data volume belongs to the gateway runtime.
- 💡A native Docker volume can avoid VM-backed bind-mount filesystem limitations, but a new empty volume does not migrate existing sessions. Stop state writers and copy data through a documented offline procedure before switching storage.
- 💡If you want the agent outcome without owning image updates, authentication, backups and gateway recovery, compare self-hosted versus managed operation and pricing.
- 💡For multiple profiles in one container, one supervised dashboard on 9119 covers Desktop/Web UI profile switching. If external OpenAI-compatible clients need several profiles, assign distinct API_SERVER_PORT values in each profile .env instead of duplicating the dashboard.
- 💡For the full local-model decision, use the Hermes Ollama setup guide and local LLM feature guide. Docker networking is only one layer; model context and tool-call reliability still need separate acceptance tests.
- 💡When Ollama runs on the host, a browser or host-shell success proves only host reachability. Always repeat the
/v1/modelsrequest from inside the Hermes container.
Troubleshooting
❌ The dashboard starts and immediately stops
✅ Check the listener inside the container: a host-loopback port mapping does not make its 0.0.0.0 bind loopback. Configure a supported authentication provider and keep the host route private or protected.
❌ State disappears after container recreation
✅ Inspect the actual mount source and /opt/data destination. A named volume and a bind mount are different stores; changing between them does not migrate data. Stop writers and restore or migrate from a verified backup instead of repeatedly recreating an empty state directory.
❌ Gateway is running but Telegram or Discord does not reply
✅ Check docker exec hermes hermes gateway status, current container logs, the active profile, token presence, allowed chats/channels, mention rules, and topic/thread routing. Then send an end-to-end test.
❌ Hermes works on the host but provider or MCP calls fail in Docker
✅ Run hermes config path, hermes config env-path, and hermes doctor inside the container. The host environment may have credentials or PATH entries that were never mounted or forwarded.
❌ Docker files are owned by the wrong UID
✅ Inspect ownership of host ~/.hermes and avoid arbitrary --user overrides unless the image explicitly supports them. Back up state before changing ownership.
❌ Port 8642 is open but the API does not respond
✅ The API server requires API_SERVER_ENABLED=true; non-loopback binding also requires API_SERVER_HOST=0.0.0.0 and an API_SERVER_KEY of at least eight characters. Do not expose it without a real need.
❌ The container says hermes update is unsupported
✅ Update the Docker image instead of the immutable application tree. Pull and recreate the service while keeping the host Hermes home mounted at /opt/data.
❌ Ollama works on the host but Hermes in Docker gets connection refused
✅ Replace 127.0.0.1 with host.docker.internal on macOS/Windows, or use the Ollama service name on a shared Compose network. Confirm Ollama listens beyond loopback when required, query /v1/models from inside Hermes, and use the exact returned model ID.
❌ Hermes reaches Ollama but says the model does not exist
✅ Run ollama list on the server and /v1/models from inside the Hermes container. Copy the exact model ID, including its tag, into the Hermes provider config; do not substitute a display name.
❌ Not sure whether to use Docker or install Hermes natively
✅ Use the Docker-vs-native decision guide to separate whole-agent Docker from the Docker terminal backend. Start native for simplest setup, use the backend for execution isolation, and containerize the whole runtime only when volumes, networking, and image recovery are explicit.
❌ State database reports WAL or filesystem errors
✅ Inspect hermes doctor warnings and the official Docker filesystem requirements. Docker Desktop bind mounts can cross a VM filesystem boundary. Choose a compatible journal/storage configuration using the documented offline procedure; never remove WAL files while Hermes is running.
FAQ
What is the official Hermes Agent Docker image?
Use nousresearch/hermes-agent:latest unless you deliberately pin a tested release tag. The official image stores mutable state in /opt/data and keeps the installed application under /opt/hermes immutable.
Where does Hermes Agent store data in Docker?
Mount host ~/.hermes to container /opt/data. It contains .env, config.yaml, SOUL.md, sessions, memories, skills, profile home directories, cron jobs, hooks, logs, and skins.
Do I need to publish port 8642?
No for chat-only gateways. Port 8642 is for the optional OpenAI-compatible API server and health endpoint. Enable and publish it only when an external client or dashboard workflow actually needs it.
Can I expose the Hermes dashboard directly to the internet?
Do not expose it without authentication and transport security. A non-loopback dashboard now fails closed unless Basic Auth, Nous OAuth, or OIDC is configured. SSH tunneling, Tailscale, or a trusted authenticated reverse proxy is safer.
Is running Hermes in Docker the same as the Docker terminal backend?
No. Full-container deployment runs Hermes, gateways, and optional dashboard inside the official image. terminal.backend: docker runs only tool commands in a hardened persistent sandbox while Hermes stays on the host.
Should each Hermes profile use a separate container?
Usually no. The official s6-based image supervises multiple profiles in one container. Use separate containers only when you need independent resource limits, image versions, networks, or credential blast radii.
When should I use FlyHermes instead of Docker?
Choose Docker for infrastructure control and custom networking. Choose FlyHermes when you want managed uptime, browser/mobile access, connected channels, and less responsibility for updates, authentication, backups, gateway recovery, and provider operations.
Do multiple Docker profiles need multiple dashboard ports?
No. One dashboard backend can serve co-located profiles. Multiple externally exposed OpenAI-compatible API servers are separate and require distinct profile-specific API ports.
How does Hermes in Docker connect to Ollama on macOS?
Use http://host.docker.internal:11434/v1 as the custom provider base URL. localhost and 127.0.0.1 inside Hermes point back to the Hermes container, not macOS.
Should Ollama run on the host or in Docker Compose?
Host Ollama is usually simplest for Mac and Windows GPU access. A sidecar is easier to reproduce on a server. For a sidecar, put both services on the same network and use http://ollama:11434/v1.
Does a host-loopback port mapping remove the dashboard authentication requirement?
No. Publishing 127.0.0.1:9119:9119 limits host exposure, but the dashboard can still bind to 0.0.0.0 inside the container. That listener requires a supported authentication provider.
Does docker compose pull replace the running Hermes image?
No. Pull downloads an image. Recreate the intended service while preserving /opt/data, then inspect its image ID and repeat the provider and channel tests. Keep the previous tested image and a compatible data backup for rollback.
Related setup and cost guides
Hermes Agent installation guide
Use the native alternative if you choose not to run the whole application in Docker.
Hermes Docker Compose tool page
Review the official image, persistent state, and operator checklist.
Hermes Docker troubleshooting
Fix UID, volume, provider, dashboard, and gateway failures.
Hermes Agent dashboard and Web UI
Use self-hosted PTY/WebSocket browser Chat, configuration and monitoring with protected access.
Hermes gateway troubleshooting
Diagnose channel delivery after the container itself is healthy.