Skip to main content

Hermes Agent — Docker

There are two distinct ways Docker intersects with Hermes Agent:

  1. Running Hermes IN Docker — the agent itself runs inside a container (this page's primary focus)
  2. Docker as a terminal backend — the agent runs on your host but executes commands inside a Docker sandbox (see Configuration → terminal.backend)

This page covers option 1. The container stores all user data (config, API keys, sessions, skills, memories) in a single directory mounted from the host at /opt/data. The image itself is stateless and can be upgraded by pulling a new version without losing any configuration.

Quick start

If this is your first time running Hermes Agent, create a data directory on the host and start the container interactively to run the setup wizard:

mkdir -p ~/.hermes
docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent

This drops you into the setup wizard, which will prompt you for your API keys and write them to ~/.hermes/.env. You only need to do this once. It is highly recommended to set up a chat system for the gateway to work with at this point.

Running in gateway mode

Once configured, run the container in the background as a persistent gateway (Telegram, Discord, Slack, WhatsApp, etc.):

docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run

Running interactively (CLI chat)

To open an interactive chat session against a running data directory:

docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent

Persistent volumes

The /opt/data volume is the single source of truth for all Hermes state. It maps to your host's ~/.hermes/ directory and contains:

PathContents
.envAPI keys and secrets
config.yamlAll Hermes configuration
SOUL.mdAgent personality/identity
sessions/Conversation history
memories/Persistent memory store
skills/Installed skills
cron/Scheduled job definitions
hooks/Event hooks
logs/Runtime logs
skins/Custom CLI skins
warning

Never run two Hermes containers against the same data directory simultaneously — session files and memory stores are not designed for concurrent access.

Environment variable forwarding

API keys are read from /opt/data/.env inside the container. You can also pass environment variables directly:

docker run -it --rm \
-v ~/.hermes:/opt/data \
-e ANTHROPIC_API_KEY="sk-ant-..." \
-e OPENAI_API_KEY="sk-..." \
nousresearch/hermes-agent

Direct -e flags override values from .env. This is useful for CI/CD or secrets-manager integrations where you don't want keys on disk.

Docker Compose example

For persistent gateway deployment, a docker-compose.yaml is convenient:

version: "3.8"
services:
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: gateway run
volumes:
- ~/.hermes:/opt/data
# 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}
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"

Start with docker compose up -d and view logs with docker compose logs -f hermes.

Resource limits

The Hermes container needs moderate resources. Recommended minimums:

ResourceMinimumRecommended
Memory1 GB2–4 GB
CPU1 core2 cores
Disk (data volume)500 MB2+ GB (grows with sessions/skills)

Browser automation (Playwright/Chromium) is the most memory-hungry feature. If you don't need browser tools, 1 GB is sufficient. With browser tools active, allocate at least 2 GB.

Set limits in Docker:

docker run -d \
--name hermes \
--restart unless-stopped \
--memory=4g --cpus=2 \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run

What the Dockerfile does

The official image is based on debian:13.4 and includes:

  • Python 3 with all Hermes dependencies (pip install -e ".[all]")
  • Node.js + npm (for browser automation and WhatsApp bridge)
  • Playwright with Chromium (npx playwright install --with-deps chromium)
  • ripgrep and ffmpeg as system utilities
  • The WhatsApp bridge (scripts/whatsapp-bridge/)

The entrypoint script (docker/entrypoint.sh) bootstraps the data volume on first run:

  • Creates the directory structure (sessions/, memories/, skills/, etc.)
  • Copies .env.example.env if no .env exists
  • Copies default config.yaml if missing
  • Copies default SOUL.md if missing
  • Syncs bundled skills using a manifest-based approach (preserves user edits)
  • Then runs hermes with whatever arguments you pass

Upgrading

Pull the latest image and recreate the container. Your data directory is untouched.

docker pull nousresearch/hermes-agent:latest
docker rm -f hermes
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run

Or with Docker Compose:

docker compose pull
docker compose up -d

Skills and credential files

When using Docker as the execution environment (not the methods above, but when the agent runs commands inside a Docker sandbox), Hermes automatically bind-mounts the skills directory (~/.hermes/skills/) and any credential files declared by skills into the container as read-only volumes. This means skill scripts, templates, and references are available inside the sandbox without manual configuration.

The same syncing happens for SSH and Modal backends — skills and credential files are uploaded via rsync or the Modal mount API before each command.

Troubleshooting

Container exits immediately

Check logs: docker logs hermes. Common causes:

  • Missing or invalid .env file — run interactively first to complete setup
  • Port conflicts if running with exposed ports

"Permission denied" errors

The container runs as root by default. If your host ~/.hermes/ was created by a non-root user, permissions should work. If you get errors, ensure the data directory is writable:

chmod -R 755 ~/.hermes

Browser tools not working

Playwright needs shared memory. Add --shm-size=1g to your Docker run command:

docker run -d \
--name hermes \
--shm-size=1g \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run

Gateway not reconnecting after network issues

The --restart unless-stopped flag handles most transient failures. If the gateway is stuck, restart the container:

docker restart hermes

Checking container health

docker logs --tail 50 hermes          # Recent logs
docker exec hermes hermes version # Verify version
docker stats hermes # Resource usage