Skip to content

Hermes Docker Setup on Local Host

Run Hermes inside Docker on the local Arch host. This keeps Hermes isolated from the full home directory while preserving Hermes config and state in ~/.hermes. A separate ~/hermes-workspace directory is used as the normal scratch workspace.

Create one persistent Hermes data directory and one scratch workspace. Do not mount the whole home directory unless Hermes should access all of it.

Terminal window
mkdir -p "$HOME/.hermes"
mkdir -p "$HOME/hermes-workspace"
chmod 700 "$HOME/.hermes"

Pull the current Hermes image and check the local image metadata.

Terminal window
docker pull nousresearch/hermes-agent
docker image inspect nousresearch/hermes-agent:latest \
--format 'ID={{.Id}}
Created={{.Created}}'

Run the setup wizard once. Hermes saves config into ~/.hermes on the host. Inside the container, the same directory appears as /opt/data.

Terminal window
docker run -it --rm \
-e HERMES_UID="$(id -u)" \
-e HERMES_GID="$(id -g)" \
-v "$HOME/.hermes:/opt/data" \
-v "$HOME/hermes-workspace:/workspace" \
-w /workspace \
nousresearch/hermes-agent setup

Start Hermes inside Docker with persistent state and the scratch workspace mounted. In this mode, Hermes can read and write files inside ~/hermes-workspace.

Terminal window
docker run -it --rm \
-e HERMES_UID="$(id -u)" \
-e HERMES_GID="$(id -g)" \
-v "$HOME/.hermes:/opt/data" \
-v "$HOME/hermes-workspace:/workspace" \
-w /workspace \
nousresearch/hermes-agent

Resume a specific Hermes session by passing the resume command after the image name. The persistent ~/.hermes mount is what lets the container find saved session state.

Terminal window
docker run -it --rm \
-e HERMES_UID="$(id -u)" \
-e HERMES_GID="$(id -g)" \
-v "$HOME/.hermes:/opt/data" \
-v "$HOME/hermes-workspace:/workspace" \
-w /workspace \
nousresearch/hermes-agent \
hermes --resume 20260528_101851_78ffa1
Terminal window
docker run -it --rm \
-e HERMES_UID="$(id -u)" \
-e HERMES_GID="$(id -g)" \
-v "$HOME/.hermes:/opt/data" \
-v "$HOME/hermes-workspace:/workspace" \
-w /workspace \
nousresearch/hermes-agent --tui

Use this only when Hermes should intentionally access the current project folder. Run it from inside the project directory.

Terminal window
cd /path/to/project
docker run -it --rm \
-e HERMES_UID="$(id -u)" \
-e HERMES_GID="$(id -g)" \
-v "$HOME/.hermes:/opt/data" \
-v "$PWD:/workspace" \
-w /workspace \
nousresearch/hermes-agent

Add short aliases for the normal Docker session and TUI mode.

Terminal window
cat >> "$HOME/.bashrc" <<'EOF'
# Hermes Agent in Docker
alias hermes-docker='docker run -it --rm -e HERMES_UID="$(id -u)" -e HERMES_GID="$(id -g)" -v "$HOME/.hermes:/opt/data" -v "$HOME/hermes-workspace:/workspace" -w /workspace nousresearch/hermes-agent'
alias hermes-docker-tui='docker run -it --rm -e HERMES_UID="$(id -u)" -e HERMES_GID="$(id -g)" -v "$HOME/.hermes:/opt/data" -v "$HOME/hermes-workspace:/workspace" -w /workspace nousresearch/hermes-agent --tui'
EOF
source "$HOME/.bashrc"
Terminal window
hermes-docker
hermes-docker-tui

Docker-based Hermes is updated by pulling the latest image. The persistent config and state in ~/.hermes remain on the host.

Terminal window
docker pull nousresearch/hermes-agent
docker image inspect nousresearch/hermes-agent:latest \
--format 'ID={{.Id}}
Created={{.Created}}'
hermes-docker

Use gateway mode only when Hermes should run as a long-lived local service. The port is bound to 127.0.0.1 so it is local-only.

Terminal window
docker rm -f hermes 2>/dev/null || true
docker run -d \
--name hermes \
--restart unless-stopped \
-e HERMES_UID="$(id -u)" \
-e HERMES_GID="$(id -g)" \
-v "$HOME/.hermes:/opt/data" \
-v "$HOME/hermes-workspace:/workspace" \
-w /workspace \
-p 127.0.0.1:8642:8642 \
nousresearch/hermes-agent gateway run
Terminal window
docker ps
docker logs -f hermes
docker stop hermes
docker start hermes
docker rm -f hermes

To update the persistent gateway, pull the latest image, remove the old container, and recreate it from the updated image.

Terminal window
docker pull nousresearch/hermes-agent
docker rm -f hermes
docker run -d \
--name hermes \
--restart unless-stopped \
-e HERMES_UID="$(id -u)" \
-e HERMES_GID="$(id -g)" \
-v "$HOME/.hermes:/opt/data" \
-v "$HOME/hermes-workspace:/workspace" \
-w /workspace \
-p 127.0.0.1:8642:8642 \
nousresearch/hermes-agent gateway run

Check the persistent data directory and scratch workspace on the host.

Terminal window
ls -la "$HOME/.hermes"
ls -la "$HOME/hermes-workspace"

This removes unused Docker objects. It does not remove ~/.hermes or ~/hermes-workspace.

Terminal window
docker system prune
  • Persistent Hermes data on host: ~/.hermes
  • Normal scratch workspace on host: ~/hermes-workspace
  • Hermes data inside container: /opt/data
  • Mounted workspace inside container: /workspace
  • Optional gateway container name: hermes
  • Optional gateway port: 127.0.0.1:8642