Skip to content

Self-update

MajNet updates itself the same way it deploys apps: through git. Which version of the control plane should run is a pinned commit in the platform repo, and changing it is a commit — reviewed, attributed, and reversible — not an SSH session.

The platform repo’s version.yaml pins the control plane:

control_plane:
ref: <source commit> # bot + reconciler + dashboard source
image: ghcr.io/…/control-plane@sha256:… # bot + reconciler (one image)
dashboard: ghcr.io/…/dashboard@sha256:…

The images are pinned by digest, never by tag — the same rule apps follow. git log version.yaml is the deploy history; rolling back is pinning an older commit.

The Control plane page (platform-admin only) is the operator surface:

  • Running vs latest — it shows the running pin alongside the newest build on the source’s main, with the image-digest diff and the commits in between.
  • Publish — one click commits the new pin to version.yaml. That commit is the update; nothing executes on the host from the browser.
  • Roll back — any past pin in the history can be re-committed in one click.

A timer on the main node polls the pin and, when it changes, pulls the pinned images and recreates the control-plane containers — bot, reconciler, and dashboard. Images are pulled before anything is swapped, so a bad pin or an unreachable registry aborts with the old control plane still up. Convergence takes about a minute.

This is a recreate, so the control plane itself is briefly unavailable during an update — a few seconds. Deployed apps are unaffected: they run on their own nodes and keep serving whether or not the control plane is mid-update. (Blue-green — start new, health-check, flip, stop old — is how app deploys roll out; it does not apply to the control plane’s own containers.)

The control plane reports its own build at /info (version, commit, build time), exactly as apps do. The dashboard compares the running build to the pinned one to show whether the platform is converged or still rolling — and drives a live progress bar through the update. Because the update is git-committed and the build is self-reported, a rollout that never converges is visible rather than silent.

If the dashboard or bot is unavailable, the main node’s updater takes an explicit ref (majnet-update <ref>) and editing version.yaml directly still works — the pin is just a file in git.