How to Deploy Hermes WebUI with Docker: Single, Two, and Three Container Setups
Purpose
This post shows how to deploy Hermes WebUI with Docker. I will cover the three official compose setups, when to use each, and the common permission issues I ran into.
Environment
- Docker with Compose plugin
- Pre-built amd64/arm64 images on GHCR
docker-compose.yml,docker-compose.two-container.yml,docker-compose.three-container.yml
The Three Setups
Hermes WebUI ships with three official Docker Compose files. Here is how they differ:
| Setup | Containers | Use Case |
|---|---|---|
| Single | 1 | Recommended for most users; agent runs in-process |
| Two | 2 | Isolates gateway (CLI/Telegram/cron) from the chat UI |
| Three | 3 | Adds a dashboard container for monitoring |

Single-Container Quickstart
This is the path I started with. It is the simplest and works for most users:
git clone https://github.com/nesquena/hermes-webuicd hermes-webuicp .env.docker.example .envdocker compose up -dThe single container runs the agent in-process inside the WebUI container. It mounts ~/.hermes and ~/workspace and auto-detects your UID/GID.

Enabling Password Protection
Before exposing the port beyond localhost, I enabled password protection:
echo "HERMES_WEBUI_PASSWORD=change-me-to-something-strong" >> .envdocker compose up -d --force-recreateTwo-Container Setup
If you need gateway isolation β for example, to run scheduled cron jobs or receive Telegram messages independently of the WebUI β use the two-container setup:
docker compose -f docker-compose.two-container.yml up -dIn this mode, tools triggered from the WebUI still run in the WebUI container, but the gateway (CLI, cron, messaging) runs separately.
Manual Docker Run
If you prefer not to use Compose, you can run the pre-built image directly:
docker pull ghcr.io/nesquena/hermes-webui:latestdocker run -d \ -e WANTED_UID=$(id -u) -e WANTED_GID=$(id -g) \ -v ~/.hermes:/home/hermeswebui/.hermes \ -e HERMES_WEBUI_STATE_DIR=/home/hermeswebui/.hermes/webui \ -v ~/workspace:/workspace \ -p 127.0.0.1:8787:8787 \ ghcr.io/nesquena/hermes-webui:latestCommon Errors and Fixes
I hit a few permission issues when I first tried this. Here is what I learned:
| Error | Cause | Fix |
|---|---|---|
PermissionError on startup | UID/GID mismatch between host and container | Use WANTED_UID and WANTED_GID env vars |
.env permission denied | fix_credential_permissions() rejects loose permissions | Set .env to 600 |
| Empty workspace in container | Bind mount points to wrong UID home | Use absolute paths, not ~ with sudo |
git: command not found | Two-container setup, tools need git in WebUI container | Install git in the WebUI image or mount host git |
Security Hardening
The production image has a few hardening measures:
- No
sudoand noNOPASSWD - Entrypoint starts as root only for UID/GID alignment, then drops to an unprivileged
hermeswebuiuser python:3.12-slimas the base image
Summary
In this post, I showed how to deploy Hermes WebUI with Docker using the official compose files. The key point is to start with the single-container setup, add password protection for remote access, and scale to multi-container only when you need gateway isolation. Watch out for UID/GID mismatches when using bind mounts.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- π¨βπ» Hermes WebUI GitHub Repository
- π¨βπ» Hermes WebUI Docker Documentation
Oh, and if you found these resources useful, donβt forget to support me by starring the repo on GitHub!
Comments