Deploy Hermes Kanban Web
Self-hosted Kanban board powered by the Hermes Agent with web terminal
ollama/ollama:latest
Just deployed
/root/.ollama
hermes-kanban-web
Just deployed
/opt/data
Deploy and Host
Deploy this template on Railway with one click. Railway provides compute, TLS at the edge, and a public URL. The service restarts automatically on failures. The template provisions two services: the hermes-kanban-web app (from the nousresearch/hermes-agent Docker image) with a persistent volume at /opt/data, plus a companion Ollama service (from ollama/ollama) with a volume at /root/.ollama for local LLM inference. The app's OLLAMA_BASE_URL is auto-linked to the sibling over the internal Railway network.
About Hosting
The app runs inside the nousresearch/hermes-agent Docker image, so the hermes CLI is on PATH and all persistent state (boards, profiles, config) lives under HERMES_HOME (/opt/data) on a Railway volume. Boards, profiles, stashed cards and theme survive redeploys and restarts. The runtime is supervised by supervisord (nginx public proxy, uvicorn FastAPI app, Hermes gateway, ttyd web terminal) running as the hermes user. The terminal at /kanban-terminal/ uses ttyd's built-in token auth (no nginx basic auth — Railway's edge proxy returns 407 when an Authorization header reaches terminal paths, so auth is delegated to ttyd's token check via a boot-hook-written credential file).
Updating Hermes
The Hermes runtime (hermes CLI + agent) is baked into the Docker image. The /opt/hermes directory in the container is the image's own runtime — it is not a persistent volume (Railway allows one volume per service, which is used for /opt/data).
- To update
hermes, open the web terminal at/kanban-terminal/and runhermes update(orpip install -U hermes-agent). The update installs to the image's/opt/hermesbut does not survive redeploys — it will revert to the base-image version on the next deploy. - If you need a persistent custom Hermes install, you would need a separate template/service pattern (not supported in this single-service template).
Why Deploy
- Zero-config self-hosting — one-click deploy, persistent volume provided, no external services to wire up.
- AI-agent-aware task board — task lifecycle operations shell out to the real
hermesCLI, so the board you manage is the same system your agents run on. - Real-time by default — SSE keeps multiple browser tabs in sync without polling.
- Optional auth — lock the board behind a bearer token in one env var; leave it empty for an open team board.
- Built-in web terminal — run
hermesCLI maintenance commands right from the browser at/kanban-terminal/(ttyd token auth). - Bundled local LLM — the companion Ollama service pre-pulls
qwen3:8bfor fully offline inference; swap to any cloud provider (OpenAI, OpenRouter, Anthropic, Groq) by setting env vars.
Common Use Cases
- Managing and visually tracking Hermes agent task queues across Todo, Ready, In Progress, Blocked, and Done.
- A lightweight team kanban that reuses existing Hermes profiles and config instead of a separate issue tracker.
- Self-hosting an AI-assisted task board with local LLM inference (no external API keys required).
Dependencies for
The template is self-contained: it needs no external databases, caches, or third-party APIs for local LLM inference.
Deployment Dependencies
- A Railway account with adequate quota for two small containers (Hobby or Pro plan).
- Provisioned automatically: the hermes-kanban-web app service + persistent volume (
/opt/data), and the Ollama companion service + persistent volume (/root/.ollama), which pre-pullsqwen3:8bon first start. - Optional: a cloud LLM provider (OpenAI-compatible, OpenAI, OpenRouter, Anthropic, or Groq) instead of the bundled Ollama.
Overview
Hermes Kanban Web is a FastAPI + vanilla JS single-page application providing a browser-based UI for Hermes agent tasks. Boards are SQLite databases, task lifecycle operations shell out to the hermes CLI, and real-time updates stream via SSE.
Features
- Multi-board support — each board is a SQLite database under
HERMES_HOME/kanban/boards/ - Drag-and-drop task management — move tasks between Todo, Ready, In Progress, Blocked, and Done columns
- Live event streaming — SSE endpoint (
GET /api/events/stream) polls board DBs every second and broadcasts task events to the frontend - Dark / light theme — persisted to browser localStorage
- Task stashing — save task cards locally (disconnected from any board)
- Profile management — list, create, rename, and delete Hermes profiles; set model/describe per profile
- Dependency tracking — parent/child task links with clickable navigation
- Active worker monitoring — real-time PID liveness checks on running task workers
- Hermes CLI integration — all task lifecycle operations (create, promote, block, complete, schedule, archive, comment) delegate to the
hermesCLI - Web terminal — a ttyd terminal at
/kanban-terminal/(ttyd token auth) gives you a bash shell with the fullhermesCLI on PATH for maintenance
Authentication (optional)
By default the board is open with no authentication. To protect the API, set HERMES_KANBAN_API_TOKEN (Railway Variables tab): leave it empty for an open board, or set it to a secret value and every API request (including the live SSE stream) must send Authorization: Bearer . Generate one with openssl rand -hex 32.
Web Terminal
A ttyd web terminal is available at /kanban-terminal/, protected by ttyd's built-in token authentication (-c user:pass):
- Credentials come from
ADMIN_USERNAME/ADMIN_PASSWORD(the template generates a randomADMIN_PASSWORDby default — read it in the Railway Variables tab after deploy; if empty at boot, a random one is printed to the container logs). - The shell is bash, running as the
hermesuser withHERMES_HOME=/opt/data, and the fullhermesCLI is on PATH — e.g.hermes kanban boards list,hermes kanban task --board --create "...",hermes profile list. A welcome banner lists the most useful commands. - Architecture: nginx (the public
PORT) routes/to the FastAPI app (uvicorn on127.0.0.1:12700) and/kanban-terminal/to ttyd (127.0.0.1:7681); ttyd enforces token auth via-c; supervisord supervises nginx, uvicorn, the Hermes gateway, and ttyd. The terminal is never exposed directly.
Why no nginx auth_basic? Railway's edge proxy (railway-hikari) intercepts terminal-like paths when an Authorization header is present, returning 407 Proxy Auth Required before the request reaches your container. Browsers send cached Basic-Auth credentials on WebSocket upgrade handshakes, which would break the ttyd connection. Delegating auth to ttyd's built-in token check (credential written by the boot hook to /etc/nginx/.ttyd-credential, chmod 600) avoids sending any Authorization header to the edge entirely.
Environment Variables
| Variable | Default | Description |
|---|---|---|
PORT | 8502 | HTTP port nginx listens on (Railway injects this automatically) |
ADMIN_USERNAME | admin | Username for the /kanban-terminal/ web terminal (ttyd token auth) |
ADMIN_PASSWORD | (generated) | Password for the /kanban-terminal/ web terminal (ttyd token auth) |
HERMES_HOME | /opt/data | Root directory for all Hermes persistent state (boards, profiles, config) — mounted as a Railway volume |
HERMES_KANBAN_API_TOKEN | (empty) | Optional bearer token; when set, all API incl. SSE require Authorization: Bearer … |
OLLAMA_BASE_URL | ${{ollama/ollama:latest.OLLAMA_BASE_URL}} | Auto-linked to sibling Ollama service (internal Railway URL) |
Data Persistence
All persistent state lives under HERMES_HOME=/opt/data (Railway volume):
config.yaml— Hermes configurationprofiles/— Hermes profileskanban/boards//kanban.db— board SQLite databases (WAL mode, idempotent migrations)kanban/stash/— stashed task cardskanban/theme.json— UI theme preference.env— LLM provider keys written by the setup wizard
LLM Setup
On first deploy, the LLM is not configured (llm_configured: false). Use the in-app setup wizard to pick a provider (Ollama, OpenAI, OpenRouter, Anthropic, Groq, DeepSeek) and model — it writes provider env vars to /opt/data/.env and runs hermes config set model . To override manually: set OLLAMA_BASE_URL / HERMES_MODEL in Railway Variables, then railway ssh -- sh -c 'hermes config set model qwen3:8b'.
Self-hosting (Docker)
docker run -d --name hermes-kanban-web -p 8502:8502 -e PORT=8502 -e HERMES_HOME=/opt/data -v hermes-data:/opt/data ghcr.io/inapp-mobile/hermes-kanban-web:latest
Template Content
ollama/ollama:latest
ollama/ollama:latesthermes-kanban-web
INAPP-Mobile/hermes-kanban-web