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 host directories
Create one persistent Hermes data directory and one scratch workspace. Do not mount the whole home directory unless Hermes should access all of it.
mkdir -p "$HOME/.hermes"
mkdir -p "$HOME/hermes-workspace"
chmod 700 "$HOME/.hermes"Pull the Docker image
Pull the current Hermes image and check the local image metadata.
docker pull nousresearch/hermes-agent
docker image inspect nousresearch/hermes-agent:latest \
--format 'ID={{.Id}}
Created={{.Created}}'Run first-time setup
Run the setup wizard once. Hermes saves config into ~/.hermes on the host. Inside the container, the same directory appears as /opt/data.
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 setupRun Hermes normally
Start Hermes inside Docker with persistent state and the scratch workspace mounted. In this mode, Hermes can read and write files inside ~/hermes-workspace.
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-agentResume a saved session
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.
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_78ffa1Run TUI mode
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 --tuiRun against a project
Use this only when Hermes should intentionally access the current project folder. Run it from inside the project directory.
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-agentCreate shell aliases
Add short aliases for the normal Docker session and TUI mode.
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"Use the aliases
hermes-docker
hermes-docker-tuiUpdate the image
Docker-based Hermes is updated by pulling the latest image. The persistent config and state in ~/.hermes remain on the host.
docker pull nousresearch/hermes-agent
docker image inspect nousresearch/hermes-agent:latest \
--format 'ID={{.Id}}
Created={{.Created}}'
hermes-dockerRun optional gateway mode
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.
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 runManage gateway container
docker ps
docker logs -f hermes
docker stop hermes
docker start hermes
docker rm -f hermesUpdate gateway later
To update the persistent gateway, pull the latest image, remove the old container, and recreate it from the updated image.
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 runCheck host data
Check the persistent data directory and scratch workspace on the host.
ls -la "$HOME/.hermes"
ls -la "$HOME/hermes-workspace"Clean unused Docker objects
This removes unused Docker objects. It does not remove ~/.hermes or ~/hermes-workspace.
docker system pruneFile locations
- 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