Run it anywhere

In-cluster

The same daemon as a Deployment with the web UI embedded — read-only RBAC by default, one journal the whole team shares.

Sometimes the right place for the watcher is inside the cluster it watches: a team view nobody's laptop has to stay open for, a journal with no gaps, an ops box in an air-gapped site. moonwayd --in-cluster runs from the pod's service account and serves the embedded web UI — same cache, same engines, same pages, reachable with a browser.

The manifest ships with the repository as deploy/moonway.yaml, and it's written to be read — every trade-off it makes is explained where it's made.

Build the image

just build-daemon-linux

That produces a static Linux binary with the UI embedded; wrap it in a two-line FROM scratch Dockerfile, tag it to match the manifest's image:, and push it to your registry.

Create the token secret

kubectl -n moonway create secret generic moonway --from-literal=token=$(openssl rand -hex 24)

The token guards the API and the UI. Anyone holding it sees what the daemon sees — treat it accordingly.

Apply and reach it

kubectl apply -f deploy/moonway.yamlkubectl -n moonway port-forward svc/moonway 8080:80

Readiness (/readyz) holds the pod out of the Service until the journal answers and every initial LIST has completed — a half-warmed cache looks exactly like a small healthy cluster, so it deliberately doesn't serve.

What the manifest grants, and why

The ClusterRole is read-only: get, list, watch on everything, plus nodes/proxy (metrics) and pods/log (log streaming). The wildcard is what makes CRD discovery work — Moonway watches whatever the cluster serves, including operators installed later.

That read includes Secrets, and the manifest is honest about what that means: Moonway redacts Secret values as they enter the cache, and the in-cluster daemon refuses the reveal path outright — a UI user cannot read values back out. But anyone holding the service account's token can talk to the API server directly; the grant is the grant. Moonway's own cluster-wide-secret-read check flags this exact shape — including on itself.

Two escalations sit in the manifest commented out, deliberately:

  • Write verbs (delete, patch) — turns on delete, restart, scale and YAML apply from the UI.
  • pods/exec — turns on the Shell tab, which in-cluster means a shell in any pod for anyone holding the Moonway token. Enable only behind authentication you trust.

One replica, and why

The journal PVC is ReadWriteOnce, and the manifest pins strategy: Recreate — at one replica, a RollingUpdate is guaranteed to start the new pod before stopping the old one, and both then want the same volume: the rollout wedges on a Multi-Attach error and never completes. For more than one replica, move the journal to --db=postgres://… and drop the PVC and the strategy together.

The pod passes Moonway's own checks — non-root, read-only root filesystem, no capabilities — because shipping a manifest our own rules would flag is how people learn to ignore the rules.