Skip to content

feat: Helm chart, production dashboard image, and Kubernetes CI/CD - #6

Merged
macjayz merged 3 commits into
mainfrom
kubernetes-helm
Oct 29, 2026
Merged

macjayz merged 3 commits into
mainfrom
kubernetes-helm

Conversation

@macjayz

@macjayz macjayz commented Oct 29, 2026

Copy link
Copy Markdown
Owner

Replaces #1 with the same chart, rebuilt on top of #3 and #4 so it merges cleanly and uses the new readiness split.

What's in it

  • Helm chart (deploy/helm/heightproof): API, worker and dashboard Deployments; optional bundled Postgres/Redis StatefulSets or external URLs; secrets reused across upgrades; migrations applied by an init container under an advisory lock; workers use the pod name as consumer name; non-root, read-only root fs, dropped caps; optional ingress, HPA, PDB; helm test.
  • Production dashboard image (static build on unprivileged nginx, API proxied on the same origin).
  • Workflows: kubernetes.yml (lint, render, kind e2e) and release.yml (multi-arch GHCR images, chart as OCI artifact on tags).

Changes from #1

Verified

helm lint clean. deploy/kind/e2e.sh on a local kind cluster: all pods Ready (API via /ready), helm test passed, 138 seeded events persisted by 2 workers. The first run of that test exposed a real bug: the consumer group was created at $, so events the API accepted before the first worker started were skipped forever. Fixed in #3 (group starts at 0, with an integration test).

Merge order: #3 → #4 → this.

Helm chart (deploy/helm/heightproof)
- API, worker and dashboard Deployments; optional bundled Postgres and
  Redis StatefulSets with PVCs, or external URLs.
- Secrets generated once and reused across upgrades (lookup), or an
  existingSecret.
- Migrations from infra/migrations (symlinked, single source) applied by
  an init container under a Postgres advisory lock.
- Workers use the pod name as Redis consumer name: the default
  worker-<pid> is worker-1 in every container, so replicas collided.
- API startup and liveness probes use /health; readiness uses /ready,
  which answers 503 when the pod cannot reach Postgres or Redis and
  ignores the worker's backlog, so a slow worker never takes API pods out
  of rotation. Alert on /health/pipeline.
- Non-root (explicit UID: images use USER node), RuntimeDefault seccomp,
  read-only root fs, dropped caps, no SA token.
- Optional ingress, HPA, PDB; Prometheus scrape annotations; helm test.

Production dashboard image: static Vite build on unprivileged nginx that
proxies /v1, /ready, /health and the /live WebSocket on the same origin.
An empty VITE_HEIGHTPROOF_API_URL now means same-origin.

Workflows
- kubernetes.yml: chart lint/render, then a kind e2e install that runs
  helm test and checks events flow API -> Redis -> worker -> Postgres.
- release.yml: multi-arch GHCR images with SBOM/provenance on main and
  tags; chart pushed as an OCI artifact on v* tags.
@macjayz
macjayz changed the base branch from refactor/dashboard-structure to main October 29, 2026 17:45
@macjayz
macjayz merged commit b797f15 into main Oct 29, 2026
8 checks passed
@macjayz
macjayz deleted the kubernetes-helm branch October 29, 2026 17:49
macjayz added a commit that referenced this pull request Oct 29, 2026
main already carries this chart via #6. Resolve every conflict to main's
version, keeping only the dashboard nginx route for /health/pipeline so
the pipeline check is reachable on the dashboard's origin too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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