Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
6.4 KiB
Appliance registry-metadata design
Goal
Remove git/branch coupling from the appliance install path. A booted appliance
must resolve a channel (stable/nightly) to an immutable set of
registry artifacts and install from them. No git branch override, no raw
GitHub content fetch, no git clone at install time.
This replaces the prior design where setup-engine read local release metadata
and profile values from git and applyFluxSource created a Flux GitRepository
(which also served the helm charts via chart: ./helm).
Artifacts (all in ghcr, published by the Argo pipeline)
All under ghcr.io/nine-minds. App images already exist; the rest are new.
-
App images (unchanged):
ghcr.io/nine-minds/alga-psa-ee:<short-sha>(+ workflow-worker, email-service, temporal-worker tags as today). -
Helm charts as OCI (new):
oci://ghcr.io/nine-minds/charts/<name>:<chartVersion>for each chart used by the appliance:sebastian(alga-core + pgbouncer),temporal,temporal-worker,workflow-worker,email-service. Pushed viahelm push. -
Flux base bundle as OCI (new):
oci://ghcr.io/nine-minds/alga-appliance-config:<version>— the renderedee/appliance/flux/overlay (namespaces, child Kustomizations, HelmReleases, profile values), with each HelmRelease's chart source rewritten to the OCI chart ref + version. Pushed viaflux push artifact. Pinned by digest. -
Control-plane image (new — published, not just baked):
ghcr.io/nine-minds/alga-appliance-control-plane:<short-sha>. Today it is only built locally and baked into the ISO (localhost/...:baked,imagePullPolicy: IfNotPresent,k3s ctr images import), so the setup UI / host-service can only be updated by re-burning an ISO. Publishing it to ghcr letsbootstrap-control-plane.shpull it (channel/digest-pinned) and roll to it — making setup-UI / host-service updates registry-only. -
Release manifest as OCI (new, the channel pointer):
oci://ghcr.io/nine-minds/alga-appliance-releasetagged:stable,:nightly, and:<version>. Its config blob is JSON:{ "schema": "alga.appliance.release/v1", "version": "1.0.3", "channel": "stable", "valuesProfile": "single-node", "images": { "algaCore": "62cdce38", "workflowWorker": "a2cbb43", "emailService": "61e4a00e", "temporalWorker": "a2cbb43" }, "controlPlane": "62cdce38", "config": { "repository": "ghcr.io/nine-minds/alga-appliance-config", "version": "1.0.3", "digest": "sha256:..." }, "charts": { "sebastian": "0.0.1", "temporal": "0.1.0", "temporal-worker": "0.1.0", "workflow-worker": "0.1.0", "email-service": "0.1.0" } }The manifest is the only mutable channel pointer; everything it references is pinned by digest/version, so a resolved release is immutable.
Control-plane (setup UI / host-service) updates without an ISO burn
The setup UI already runs in k8s (the appliance-control-plane Deployment,
deployed by bootstrap-control-plane.sh), but its image is baked + imported, so
UI/engine changes still require an ISO. To finish that goal:
- Publish the control-plane image to ghcr (artifact #4) and add
controlPlaneto the release manifest. - Keep a baseline control-plane image baked in the ISO so first boot can serve the UI with no network dependency.
- On boot,
bootstrap-control-plane.shresolves the channel's release manifest, and ifcontrolPlanediffers from the baked baseline, pulls it from ghcr and rolls the Deployment to it. Result: setup-UI / host-service updates become a channel repoint — no ISO. The ISO then only needs re-burning for k3s / base OS / Flux controllers / systemd units / the autoinstall seed.
Consume side (ee/appliance/host-service/setup-engine.mjs)
resolveChannelMetadata: HTTP to ghcr registry API — token (GET /token?scope=repository:nine-minds/alga-appliance-release:pull) →GET /v2/.../manifests/<channel>→ fetch the config blob = the release manifest JSON. No git.applyFluxSource: create a Flux OCIRepository (source.toolkit.fluxcd.io) atconfig.repositorypinned toconfig.digest, plus a Kustomization withsourceRef: { kind: OCIRepository }. No GitRepository.- Image tags come from
manifest.images, injected into the per-release values ConfigMap exactly as today. - The flux-base HelmReleases (inside the config bundle) reference OCI charts pinned to
manifest.charts[name]. validateSetupInputs: keepchannel; optional advanced override pins to a specificversion/digest.
Publish side (Argo, ~/nm-kube-config/alga-psa/workflows)
The publish stage is owned by the ~/nm-kube-config Argo workflow and is gated
on release/promote parameters (auth via the existing github-token secret, user
robertisaacs):
helm package+helm push oci://ghcr.io/nine-minds/charts/<name>for each chart.- Render
ee/appliance/flux/with chart sources rewritten to OCI refs+versions;flux push artifact oci://ghcr.io/nine-minds/alga-appliance-config:<version>(capture digest). - Build the release manifest JSON (images from the build, config digest from step 2, chart versions from step 1) and
oras push oci://ghcr.io/nine-minds/alga-appliance-release:<channel>(and:<version>).
Decisions (made, with rationale)
- Full OCI (charts + flux base + manifest all in the registry) rather than a host-templated base — it keeps base/structure changes out of the control-plane image (a new bundle artifact, not a rebuild) and is Flux-native.
- Channel = OCI tag on the release manifest; everything else pinned by digest/version for immutability.
- ghcr only for now (the appliance already requires ghcr egress; the preflight
already checks
ghcr.io/v2/). Harbor mirror optional later. - Public read on these metadata/chart artifacts (no pull secret needed), matching how images are pulled today.
Bootstrapping / rollout
- Publishing requires the Argo additions to run. To validate the consume side
before wiring CI, the artifacts can be published once manually from a
workstation (
helm push,flux push artifact,oras pushwith aghtoken). - This engine change ships in the control-plane image, so one more control-plane image build + ISO is needed; after that, channel/tag/release changes are registry-only (publish artifacts → appliance picks them up; no control-plane rebuild, no ISO, no branch).