Docker
Hermes Agent can be installed using Docker Compose with full configuration management.
Prerequisites
- Docker and Docker Compose plugin installed (
docker compose versionshould work). - User has
sudoprivileges or is in thedockergroup. - Ports
8642and9119are available on the host (open in firewall if needed).
Prepare Directory
mkdir -p ~/hermes && cd ~/hermes
mkdir -p data
Place the docker-compose.yml file (below) in ~/hermes.
Directory structure after this step:
hermes/
├── docker-compose.yml
├── .env ← created in step 3
└── data/ ← Hermes stores data here, config.yaml will be in here
docker-compose.yml
services:
hermes:
image: nousresearch/hermes-agent:v2026.8.16
container_name: hermes
restart: unless-stopped
command: gateway run
shm_size: '1g'
ports:
- "8642:8642"
- "9119:9119"
volumes:
- ./data:/opt/data
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
env_file:
- .env
environment:
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_ALLOWED_USERS=${TELEGRAM_ALLOWED_USERS}
- GBRAIN_TOKEN=${GBRAIN_TOKEN}
- HERMES_DASHBOARD=1
- HERMES_DASHBOARD_HOST=0.0.0.0
- HERMES_DASHBOARD_BASIC_AUTH_USERNAME=${HERMES_DASHBOARD_BASIC_AUTH_USERNAME}
- HERMES_DASHBOARD_BASIC_AUTH_PASSWORD=${HERMES_DASHBOARD_BASIC_AUTH_PASSWORD}
- HERMES_DASHBOARD_BASIC_AUTH_SECRET=${HERMES_DASHBOARD_BASIC_AUTH_SECRET}
- BUZZ_RELAY_URL=${BUZZ_RELAY_URL}
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"
Create .env File
Create .env file in the same directory as docker-compose.yml:
nano .env
Paste the following, replacing <...> with your actual values:
# --- Telegram bot ---
TELEGRAM_BOT_TOKEN=<your Telegram bot token, get from @BotFather>
TELEGRAM_ALLOWED_USERS=<comma-separated list of allowed Telegram user IDs>
# --- GBrain ---
GBRAIN_TOKEN=<your GBrain token>
# --- Dashboard auth (required in newer Hermes versions) ---
HERMES_DASHBOARD_BASIC_AUTH_USERNAME=admin
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD=<strong password you choose>
HERMES_DASHBOARD_BASIC_AUTH_SECRET=2937510f3e81bc78f57b75f1dcc487993976c9558ed5f13213d1bca4d36e0d84
# --- Buzz relay (if you use related features) ---
BUZZ_RELAY_URL=<your relay URL, leave empty if not using>
The sample secret above was generated using
openssl rand -hex 32— you can use it as-is, or generate your own:openssl rand -hex 32
Protect this file:
chmod 600 .env
Do not commit .env to git. If using git, add .env to .gitignore.
Environment Variables Explained
| Variable | Description |
|---|---|
TELEGRAM_BOT_TOKEN | Token for Hermes to control your Telegram bot. |
TELEGRAM_ALLOWED_USERS | Blocks unauthorized users — only listed user IDs can send commands. |
GBRAIN_TOKEN | Token for connecting to GBrain service. |
HERMES_DASHBOARD=1 | Enables the web dashboard. |
HERMES_DASHBOARD_HOST=0.0.0.0 | Makes dashboard listen on all network interfaces in the container (published to host port via ports:). |
HERMES_DASHBOARD_BASIC_AUTH_USERNAME / _PASSWORD | Dashboard login credentials — required when binding to 0.0.0.0. |
HERMES_DASHBOARD_BASIC_AUTH_SECRET | Secret used to sign session tokens; keep consistent across restarts to avoid logout. |
BUZZ_RELAY_URL | Relay URL for Buzz feature (leave empty in .env if not used). |
About ports:
8642:8642— Main Hermes API/gateway port.9119:9119— Dashboard web port, accessible viahttp://<server-ip>:9119.
About shm_size: '1g' — Increases shared memory for the container, useful if Hermes uses headless browser or processes heavy tasks internally.
About deploy.resources.limits — Limits container to max 4GB RAM and 2 CPU cores. Note: this only works in Docker Swarm mode; for regular docker compose, you may need to use mem_limit / cpus at service level instead.
Note: If you need to share a network (
hermes-net) with other containers, add:networks: - hermes-net networks: hermes-net: external: true name: hermes-net
Run Hermes
cd ~/hermes
docker compose up -d
Check logs to ensure no auth provider warnings:
docker compose logs -f hermes
If everything is fine, you should no longer see “Refusing to bind dashboard…” messages.
Access Dashboard
Open browser:
http://<server-ip>:9119
Login with HERMES_DASHBOARD_BASIC_AUTH_USERNAME / HERMES_DASHBOARD_BASIC_AUTH_PASSWORD from .env.
Useful Commands
| Task | Command |
|---|---|
| View realtime logs | docker compose logs -f hermes |
| Restart container | docker compose restart hermes |
| Stop | docker compose down |
| Update to new image | docker compose pull && docker compose up -d |
| Enter container shell | docker compose exec hermes sh |
| Check generated config | cat ./data/config.yaml |
Additional Security Recommendations
- If your server has a public IP, restrict port
9119/8642in firewall to your IP only, instead of opening to the entire internet. - Consider placing Hermes behind a reverse proxy (Nginx/Caddy) with HTTPS if accessing dashboard remotely frequently.
- Change dashboard password periodically; don’t reuse passwords from other services.
- Backup
./datadirectory regularly as it containsconfig.yamland Hermes state data.
Troubleshooting
Still seeing “Refusing to bind dashboard to 0.0.0.0”
→ Check that .env has all three HERMES_DASHBOARD_BASIC_AUTH_USERNAME/PASSWORD/SECRET variables, and the container is reading the correct .env file (relative path must match the directory where you run docker compose up).
Container won’t start / exits immediately
→ Check logs: docker compose logs hermes. Usually due to missing required variables or invalid token format.
Cannot access dashboard from another machine
→ Check server firewall (ufw status or security group if using cloud) to ensure port 9119 is open.