Deckhand is a day-2 operations dashboard for CloudNativePG. It ships as a single binary/container with an embedded React SPA, watches CNPG resources in Kubernetes, scrapes per-pod metrics, and exposes REST plus WebSocket surfaces for live cluster health, backup management, and guided restore workflows.
- Live CNPG visibility — overview, detail, backup, and restore routes are powered by the current Kubernetes-backed runtime snapshot.
- Backup and restore workflows — trigger on-demand backups, inspect backup history, and create restore target clusters from the UI.
- Truthful live updates — the frontend listens on
/wsand refetches authoritative API routes instead of trusting optimistic client state. - Single-pod packaging — the Helm chart installs one Deployment that serves both the API and the embedded SPA.
- Least-privilege RBAC — the chart supports cluster-wide and namespace-scoped installs with the same resource matrix.
Cluster-wide install:
helm install deckhand charts/deckhandNamespace-scoped install:
helm install deckhand charts/deckhand \
--set rbac.clusterWide=false \
--set "rbac.namespaces={production,staging}"What you get:
ClusterRole/ClusterRoleBindingfor cluster-wide installs, or per-namespaceRole/RoleBindingobjects for scoped installs- a single Deckhand pod serving the API, WebSocket endpoint, and embedded SPA on port
8080 - namespace filtering via
DECKHAND_NAMESPACESin scoped mode
For chart details and RBAC mode notes, see charts/deckhand/README.md.
make buildThat target runs the frontend build first, embeds web/dist, and then produces the deckhand binary from ./cmd/deckhand.
make testInstall dependencies once:
npm --prefix web ciRun the Vite dev server:
npm --prefix web run devBy default, Vite proxies /api and /ws to http://127.0.0.1:8080. Override that with DECKHAND_DEV_BACKEND if your backend runs elsewhere.
Deckhand needs either in-cluster credentials or an explicit kubeconfig path.
go run ./cmd/deckhand --kubeconfig "$KUBECONFIG" --listen 127.0.0.1:8080Useful runtime flags and env vars:
--listen/DECKHAND_LISTEN— HTTP listen address--kubeconfig/KUBECONFIG— kubeconfig path for local runs--namespaces/DECKHAND_NAMESPACES— comma-separated namespace scope
GET /healthz— health checkGET /api— version documentGET /api/clusters— overview list with namespace filter supportGET /api/clusters/{namespace}/{name}— cluster detail summaryGET /api/clusters/{namespace}/{name}/metrics— per-instance metrics snapshotGET|POST /api/clusters/{namespace}/{name}/backups— history plus on-demand backup creationGET|POST /api/clusters/{namespace}/{name}/restore— restore options plus restore creationGET /api/clusters/{namespace}/{name}/restore-status— restore progress for the target clusterGET /ws— change-notification stream used for live refetches
Need request/response examples or RBAC details? Jump straight to the published references:
docs/api.mdfor the REST + WebSocket contract and example payloadsdocs/permissions.mdfor the exact Helm RBAC matrix and install-mode behavior
- Architecture overview
- API reference
- Permissions and RBAC
- Releasing
- Contributing guide
- Helm chart README
cmd/deckhand/ main entrypoint and runtime wiring
internal/api/ REST handlers, DTOs, and WebSocket hub
internal/k8s/ Kubernetes bootstrap, watchers, backup/restore creators
internal/metrics/ CNPG metrics scraping and health evaluation
internal/store/ in-memory runtime snapshot and change events
web/ embedded React SPA and frontend tests
charts/deckhand/ Helm packaging and RBAC modes
See CONTRIBUTING.md for the current Go, Node, Make, and Helm workflow used in this repository.
Deckhand is licensed under the Apache License, Version 2.0.


