Skip to content

slim-shim: replace /setup with Caddy + native dashboard - #8

Merged
tomfuertes merged 2 commits into
mainfrom
slim-shim
May 1, 2026
Merged

tomfuertes merged 2 commits into
mainfrom
slim-shim

Conversation

@tomfuertes

Copy link
Copy Markdown
Contributor

Summary

  • Drops the 1500-line Python admin server and the hand-rolled Alpine.js SPA at /setup
  • Caddy at \$PORT terminates basic auth and reverse-proxies to the native hermes dashboard on 127.0.0.1:9119
  • start.sh becomes a 40-line supervisor: dashboard + caddy in background, hermes gateway run --replace in foreground (under tini)
  • Net diff: +48 / −2730 across 6 files

Why

  • hermes CLI already provides everything /setup was wrapping: hermes pairing, hermes config, hermes status, hermes dashboard. The /setup UI was a parallel implementation over the same JSON files and .env.
  • hermes gateway run --replace (upstream) supersedes the manual stale-PID cleanup + in-memory state machine that caused the recurring "Gateway State: error" desync.
  • The only irreducible thing the Python server did was sit in front of the dashboard with basic auth — Caddy does that in ~10 lines.

Operator surface area after this PR

  • Web UI: native hermes dashboard at / (already proxied today, just no longer wrapped by /setup)
  • Config edits: railway ssh → hermes config set …, or Railway variables (no more .env-shadows-os.environ inversion)
  • Pairing: railway ssh → hermes pairing list / approve / deny, or the native dashboard's pairing UI
  • Logs: railway logs
  • Restart: railway redeploy or stop the gateway via SSH (hermes gateway run --replace handles re-entry)

Test plan

  • railway up (or switch service's deploy branch to slim-shim) and confirm the container boots
  • GET /health returns 200 without auth
  • GET / prompts for basic auth, then loads the native hermes dashboard
  • WebSocket endpoints (/api/pty, /api/ws, /api/events) work through the proxy — open the embedded Chat tab
  • Configure LLM_MODEL + a provider key via hermes config set over SSH; gateway starts cleanly
  • DM the Slack bot from a new user → hermes pairing list shows the request → hermes pairing approve <code> → bot replies
  • Trigger Railway redeploy → verify no "PID file race lost" errors (the --replace path)
  • Confirm /setup returns 404 (it should — that route is gone)

Rollback

Revert by switching the service back to main in Railway and redeploying. Branch is non-destructive to main.

tomfuertes added 2 commits May 1, 2026 13:22
Drop the 1500-line Python admin server and the hand-rolled Alpine.js
SPA. Replace with:

- Caddy at $PORT terminating basic_auth → reverse_proxy to the native
  hermes dashboard on 127.0.0.1:9119.
- start.sh as a tiny supervisor: runs hermes dashboard in background,
  caddy in background, hermes gateway in foreground (under tini).
- `hermes gateway run --replace` supersedes the manual stale-PID
  cleanup the old setup needed; it's also why the in-memory gateway
  state machine in server.py existed in the first place.

Operator surface area moves to the native dashboard plus the upstream
CLI: `hermes pairing`, `hermes config`, `hermes status` via railway
ssh. The /setup curated channel UI is gone — channels are configured
in the native dashboard's config tab.

-2682 net lines.
The native dashboard's web_server enforces a Host check unless
launched with --insecure (which we don't want — it disables every
binding-related guard). Caddy's default reverse_proxy preserves the
original public Host (e.g. your-app.up.railway.app), which the
dashboard rejects with "Invalid Host header. Dashboard requests must
use the hostname the server was bound to."

`header_up Host {upstream_hostport}` rewrites Host to 127.0.0.1:9119
on the upstream hop so the dashboard sees what it expects.
X-Forwarded-Host preserves the original for any downstream code that
wants it (link generation, redirects).
@tomfuertes
tomfuertes marked this pull request as ready for review May 1, 2026 18:33
@tomfuertes
tomfuertes merged commit 6379e33 into main May 1, 2026
@tomfuertes
tomfuertes deleted the slim-shim branch June 24, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant