The Complete Guide to Running Hermes Agent in Docker

Based on the official Hermes Agent documentation, this guide systematically covers the core concepts of running Hermes in Docker, the pros and cons, how to run subcommands, and Profiles configuration.

Two Ways to Interact with Docker

Hermes Agent interacts with Docker in two distinct modes, clearly separated in the official docs:

  • Running Hermes in Docker (the focus of this article): the agent itself runs inside the container, with all user data persisted to the host via mounted volumes.
  • Docker as a terminal backend: the agent runs on the host, but specific commands execute inside a Docker sandbox. This mode is enabled via the terminal.backend configuration.

The rest of this article covers the first mode.

Quick Start: Three Ways to Run

1. First-time initialization (setup wizard)

This command launches the interactive setup wizard, writing API keys to ~/.hermes/.env. This step only needs to run once.

2. Gateway mode (long-running daemon)

For long-term integration with messaging platforms such as Telegram, Discord, Slack, and WhatsApp.

3. Interactive CLI mode

For starting an ad-hoc chat session.

Persistent data directory structure

Inside the container, /opt/data maps to ~/.hermes/ on the host and is the single source of truth for all Hermes state, including:

Path Contents
.env API keys and secrets
config.yaml All Hermes configuration
SOUL.md Agent persona/identity definition
sessions/ Conversation history
memories/ Persistent memory
skills/ Installed skills
cron/ Scheduled task definitions
hooks/ Event hooks
logs/ Runtime logs
skins/ Custom CLI skins

Containerized vs Running Directly on the Host

Main advantages of containerization

Advantage Explanation
Environment consistency The official image ships with all dependencies preinstalled — Python, Node.js, Playwright + Chromium, ripgrep, ffmpeg, WhatsApp bridge, etc. Running on the host requires manually setting up the virtual environment and browsers.
Dependency isolation Hermes’s Node version, Playwright browser binaries, etc., won’t conflict with other projects on the host.
Stateless upgrades The image itself is stateless; all data lives in the mounted directory. Upgrading is simply docker pull of the new image, with no config loss.
Resource control --memory and --cpus let you explicitly cap container resources, preventing browser automation or long tasks from exhausting the host.
Portability Back up the ~/.hermes directory, and you can restore the full environment on any machine with the same mount command.
Good for long-running services docker run -d --restart unless-stopped is a great fit for running Hermes as a background Gateway service.

Main disadvantages of containerization

Disadvantage Explanation
Concurrency limits The official docs explicitly forbid two containers mounting the same data directory concurrently. A single host process naturally doesn’t have this problem.
Permission issues The container starts as root by default, so files written to ~/.hermes may end up owned by root on the host, causing permission errors if you later run directly on the host.
Browser tools need extra config Playwright/Chromium need shared memory inside the container; you must add --shm-size=1g or they may crash.
Large image size Debian-based and bundling full browser engines, the image is much larger than a pure-Python environment.
Extra debugging layer Viewing logs, editing code, and running tests all go through docker exec or docker logs, which is less direct than host-side development.
Harder troubleshooting If .env is missing or the config is wrong, the container exits immediately, and newcomers have to check docker logs to find out why; running interactively on the host shows the errors directly.

Recommendations

  • Prefer Docker when: you want out-of-the-box, fast deployment, a long-running background Gateway, or a messy host environment you’d rather not configure manually.
  • Prefer the host when: you need frequent development and debugging, care about file permissions, rely heavily on browser automation, or want to minimize resource overhead.

If you plan to mix both (Docker for the Gateway + host CLI for debugging), watch out for the file permission issues created by the container.

Two Key Practical Questions

1. How do you run other subcommands while the Gateway runs in the foreground?

The container’s startup command hermes gateway run is a foreground process. There are two ways to run other subcommands:

Option A: docker exec into the running container (recommended)

Option B: start a one-off temporary container

2. Are Profiles available in a containerized setup?

Yes, but you must explicitly set the HERMES_HOME environment variable.

Looking at the hermes_constants.py source, Hermes explicitly handles profile path detection in Docker scenarios: when HERMES_HOME points to <root>/profiles/<name>, the system correctly resolves its root directory.

Usage example:

As long as -v ~/.hermes:/opt/data is mounted correctly, profile data persists on the host. The entrypoint.sh also automatically creates a home/ subdirectory, so configs for subprocesses like git, ssh, and npm land in the persistent volume too.

If HERMES_HOME isn’t explicitly set, /opt/data is used by default, which is equivalent to running hermes directly on the host (without the -p flag) in the default profile mode.

Summary

Deploying Hermes Agent in Docker decouples config from the image via a single mount volume, keeping the stateless-upgrade advantage while ensuring data persistence. For users who want Hermes as a long-running background Gateway, Docker is the lowest-friction option.

But in practice, keep three things in mind:

  1. Never mount the same data directory into multiple containers concurrently;
  2. Run subcommands via docker exec to avoid spinning up conflicting containers;
  3. Profiles are fully supported in Docker — the key is explicitly setting -e HERMES_HOME=/opt/data/profiles/<name>.

If you’re still hesitating between host and container, run the setup wizard in Docker and try Gateway mode first; once it’s stable, decide whether to adopt it long-term.