Hermes Agent

How-To Guide

Run Hermes commands in a Docker sandbox

Configure the Hermes Docker terminal backend with narrow mounts, deliberate persistence, resource limits and tests for the actual execution boundary.

Quick answer

The Docker backend routes terminal, file and execute_code tools into an execution container. It is separate from running the whole Hermes gateway in Docker Compose. Mounts, forwarded credentials, networking and additional tools still determine what the agent can reach; a container is not a guarantee that every capability is isolated.

Choose this backend when Hermes should stay on the host while its execution tools use Docker. The backend decision guide helps distinguish the effective backend from a TERMINAL_ENV override. For an always-on application container, use the Docker install guide instead.

See the price →

$49/mo or $39/mo billed yearly · AI included · 14‑day guarantee

Before you start:

  • ☑Hermes Agent installed
  • ☑Docker installed and running
  • ☑Sufficient disk space for container images (~2GB)

Steps

  1. 1

    Verify Docker under the gateway account

    Run docker version from the account that launches Hermes. A shell on your laptop and a background service may have different Docker access. Resolve the daemon or socket error before changing provider settings.

  2. 2

    Select Docker in the active profile

    Run hermes config path to find the configuration in use, then set terminal.backend: docker in that file. Inspect any TERMINAL_ENV override first. The profiles guide explains how service and CLI state can differ.

  3. 3

    Choose an image deliberately

    Current official configuration documents nousresearch/hermes-sandbox:desktop for the integrated screen/browser sandbox. Shell-only custom images remain possible, but do not assume they include that display stack. An explicit image change can recreate an existing sandbox; preserve work before changing it.

  4. 4

    Choose shared persistence or per-session isolation

    Current defaults reuse a long-lived sandbox across sessions and Hermes process restarts. For one fresh sandbox per conversation, set terminal.container_persistent: false; subagents still share their parent session container. A new chat alone does not isolate the default shared sandbox. Verify the installed version supports this lifecycle before relying on it.

  5. 5

    Grant only the required filesystem and credentials

    For a read-only task folder, add terminal.docker_volumes: ["/absolute/path/to/data:/workspace/data:ro"]. Keep the entire Hermes home and Docker socket out of that list. Use docker_forward_env only for specific needed variables; skills can also declare required environment variables. See Docker/Discord file-access repair if a gateway task cannot find a host path.

  6. 6

    Set limits and test the boundary

    Set container_cpu and container_memory under terminal for the workload. The documented container_disk limit requires overlay2 on XFS with project quotas; do not assume it is enforced on every Docker host. Test one allowed read, one rejected write to a :ro mount and one inaccessible unrelated path. Use security hardening before expanding access.

Pro Tips

  • 💡A persistent filesystem does not guarantee surviving background processes after a Docker daemon restart, host reboot or OOM.
  • 💡With default profile/environment scoping, image or mount changes select a new environment. An explicit docker_shared_container_key opts trusted profiles into sharing; the first creator's immutable image/mount settings win.
  • 💡Setting docker_network: false removes execution-container networking, but can replace an existing networked sandbox and stop its processes. Plan for that interruption.
  • 💡Review self-hosted versus managed operation and pricing if maintaining Docker is not part of your intended workflow.

Troubleshooting

❌ Docker reports socket permission denied

✅ Check the service account and daemon/socket ownership. On Linux, Docker group membership grants powerful host access; do not add it casually or make the socket world-writable. Docker Desktop has different access controls.

❌ A host folder is missing

✅ Use an explicit narrow mount, then inspect the actual sandbox path. docker_mount_cwd_to_workspace exposes the working directory and may reveal more files than the task needs.

❌ The sandbox fills the host disk

✅ Inspect Docker storage usage and identify disposable data before deleting anything. Increasing container_disk does not create host space, and its quota support depends on the storage driver. Do not use a broad prune without a backup and review.

❌ A new session still sees previous files

✅ That is expected for the default persistent sandbox. Use supported per-session isolation when conversations must not share execution state, then verify with harmless canary files in separate sessions.

FAQ

What does the Docker terminal backend isolate?

It routes terminal, file and execute_code tools into a container. Host mounts, forwarded credentials, networking, extra Docker flags and other enabled tools still affect access. Review those separately rather than assuming the entire agent is isolated.

Is it the same as running Hermes in Compose?

No. Compose can run the whole agent and gateway. The terminal backend controls the execution environment for tools. The application data mount and sandbox task mounts serve different purposes.

Does a new chat get a fresh Docker container?

Not with the current default persistent mode. For per-session containers, use container_persistent: false on a version that supports the documented behavior. Subagents share the parent session container.

Should I forward every provider key into Docker?

No. Forward only credentials required by the sandbox task, and review skills that declare required environment variables. Model access in the Hermes runtime is different from a shell tool needing a token inside the sandbox.

Related Guides