Enable the dashboard sidecar¶
This guide shows you how to turn on upstream's hermes dashboard as a sidecar container in your agent Pod. Enabling the dashboard gives you an HTTP UI + REST API for the running agent and populates status.gateways[] on the CR via 30s polling of the sidecar's /api/status endpoint.
For exposing the dashboard outside the cluster with auth, follow up with Expose the dashboard externally with auth.
What you get¶
- A
dashboardsidecar container runninghermes dashboard --insecure --host 0.0.0.0 --no-openon port 9119. pod.spec.shareProcessNamespace: trueon the agent Pod (mandatory; upstream uses PID-based liveness detection).- A
Service/hermes-<name>-dashboard(ClusterIP, port 9119,publishNotReadyAddresses: trueso observability survives gateway outages). /api/status(unauthenticated): JSON with per-platform connection state. The operator polls this directly.- The SPA at
/and admin endpoints (/api/config,/api/env,/api/cron/jobs): gated by an ephemeral session token the dashboard embeds in the rendered HTML.
Enable it¶
apiVersion: hermes.k8s.undermountain.cc/v1alpha1
kind: HermesAgent
metadata: { name: my-agent, namespace: hermes }
spec:
image: docker.io/nousresearch/hermes-agent:v2026.4.30
storage:
persistentVolumeClaim:
accessModes: [ReadWriteOnce]
resources: { requests: { storage: 50Gi } }
dashboard:
enabled: true
Apply and the operator adds the sidecar + Service on the next reconcile.
Reach it via port-forward¶
The SPA loads with the session token embedded, so the browser session can talk to admin endpoints. Closing the tab effectively logs you out.
Inspect per-gateway status from kubectl¶
Once the dashboard is enabled, status.gateways[] populates within the 30s polling window:
Each entry has type, ready, state (connecting / connected / retrying / fatal / disconnected), and message (populated for fatal states).
Expose externally¶
Set spec.dashboard.ingress.enabled: true and the operator reconciles an Ingress. You must layer external authentication in front of it; see Expose the dashboard externally with auth. The CRD documents the requirement but does not enforce specific annotations.
Tradeoffs to understand¶
shareProcessNamespace: trueis mandatory. Every container in the Pod can see every other's process tree. This is a real isolation reduction, but acceptable in a single-tenant Pod and unavoidable as long as upstream stays PID-based for liveness detection.- Sidecar runs as UID 10000. The operator stamps
securityContext.runAsUser: 10000on the sidecar so it does not write to/opt/dataas root, which would crash the gateway. - The operator hardcodes safe flags. Do not pass
--tuitohermes dashboard: it would spawn a second hermes process contending with the gateway overgateway.lock. The operator's flags are not user-overridable for this reason.
See also¶
- Expose the dashboard externally with auth — Ingress with TLS and an auth proxy.
- Reference: HermesAgent API — every dashboard field.
- Known Hermes upstream behaviours — the auth model and shared-PID rationale.