# Hermes Web UI — Docker Compose configuration template # # Copy this file to `.env` next to your docker-compose.yml. # All variables are optional — Docker Compose substitutes defaults if unset. # # cp .env.docker.example .env # # edit values you care about, then: # docker compose up -d # ────────────────────────────────────────────────────────────────────────── # UID / GID — host user mapping # ────────────────────────────────────────────────────────────────────────── # Critical when bind-mounting an EXISTING host directory (e.g. ~/.hermes). # The container runs as UID/GID and must match your host file ownership, # otherwise the container can't read your config.yaml or write sessions. # # Find yours: id -u (UID) | id -g (GID) # # On macOS, UIDs start at 501 (not 1000), so you MUST set these. # On Linux, the default of 1000 usually matches the first interactive user. # # REPLACE THESE WITH YOUR ACTUAL VALUES (run `id -u` and `id -g`): UID=1000 GID=1000 # ────────────────────────────────────────────────────────────────────────── # Hermes home directory — single-container compose only # ────────────────────────────────────────────────────────────────────────── # Where on the host your config, sessions, skills, and state live. # Default: ~/.hermes (works for everyone with a standard install) # Override if your .hermes is elsewhere: # HERMES_HOME=/opt/hermes-data # ────────────────────────────────────────────────────────────────────────── # Workspace directory — single-container compose # ────────────────────────────────────────────────────────────────────────── # Path to your code/project directory. The WebUI's file browser shows # this at /workspace inside the container. # Default: ~/workspace # HERMES_WORKSPACE=/home/me/dev # ────────────────────────────────────────────────────────────────────────── # Password — protect remote access # ────────────────────────────────────────────────────────────────────────── # REQUIRED if you expose the container on anything other than 127.0.0.1. # Without a password, anyone who can reach the port can run commands as # the agent. # HERMES_WEBUI_PASSWORD=change-me-to-something-strong # ────────────────────────────────────────────────────────────────────────── # Permission handling for bind-mounted .hermes — advanced # ────────────────────────────────────────────────────────────────────────── # By default, the WebUI's startup credential-permission fixer enforces # 0600 mode on .env, auth.json, and similar credential files in HERMES_HOME. # This is the right behavior on a clean install, but it can clash with: # # - Bind-mounting an EXISTING ~/.hermes whose .env is intentionally 0640 # (e.g. group-readable for a Docker user group) # - HERMES_HOME_MODE configured at the agent level for a multi-user setup # # To bypass the WebUI's fixer entirely: # HERMES_SKIP_CHMOD=1 # # OR to allow group bits while still stripping world-readable: # HERMES_HOME_MODE=0640 # # ⚠️ MULTI-CONTAINER WARNING: HERMES_HOME_MODE has DIFFERENT semantics in # the WebUI vs. the agent image: # - WebUI: credential FILE mode threshold (0640 = allow group bits) # - Agent: HERMES_HOME *directory* mode (default 0700) # 0640 on a directory has NO execute bit, so the agent can't enter its own # home → broken. If you set HERMES_HOME_MODE for a multi-container setup, # use 0750 (group-traversable) or 0701 (x-only for non-owner traversal). # The compose files document both correctly per-service. # ────────────────────────────────────────────────────────────────────────── # Multi-container only — used by docker-compose.two-container.yml and # docker-compose.three-container.yml # ────────────────────────────────────────────────────────────────────────── # These compose files use named Docker volumes by default (recommended). # Set the variables above to your host UID/GID — both the agent container # (HERMES_UID/HERMES_GID) and the webui container (WANTED_UID/WANTED_GID) # are derived from $UID/$GID so files written by one are readable by the # other. # # If you switch to bind mounts (replacing `hermes-home: {}` with a `device:` # bind), ALL THREE containers must mount the SAME host path and run as the # SAME UID/GID. Mismatched UIDs → "Permission denied" → the WebUI crashes # on every HTTP request because it can't read its own auth signing key.