Skip to content

Upgrading

How to move the Dashboard to a new version safely, and how to roll back if you must.

TL;DR

  1. Back up the state store first (Backup & recovery) — it's the only supported rollback path.
  2. Deploy the new version — schema migrations run forward-only at startup, automatically.
  3. Run the post-deploy checklist.
  4. Rollback = restore the pre-upgrade backup (rolling code back onto a migrated DB is refused — see below).

What changes vs. what doesn't

  • What can change: the state-store schema (new forward-only migrations), the /api surface (guarded by generated SPA types, ADR-010), and the SPA. The kneo-client floor can rise (see the platform compatibility floors).
  • What doesn't: your data (migrations are additive/idempotent, never destructive in a single step), your config env vars (additions only; see the environment reference), and the same-origin / OIDC model.

The authoritative per-version list of changes is the CHANGELOG and the release notes; this page is the procedure.

Upgrade procedure

Container (recommended). Pin by digest, then roll the image forward:

# 1. back up the state volume first (see Backup & recovery)
# 2. pull + restart with the new tag/digest
docker compose -f examples/docker-compose.prod.yml pull
docker compose -f examples/docker-compose.prod.yml up -d

pip install. pip install -U kneo-dash (or your pinned version), then restart the service.

On startup the BFF applies every migration past the recorded schema_version (forward-only, idempotent; on Postgres a replica advisory-lock serializes concurrent cold-starts). No manual migration step. A DB newer than the running build fails fast (SchemaTooNewError) rather than risk running on an unknown schema — which is exactly the rollback guard below.

Rollback

Migrations are forward-only — there is no downgrade migration. Rolling the code back onto a DB that a newer build already migrated is refused at startup (the downgrade guard, ADR-012 §5). So rollback is restore, not reverse:

  1. Stop the new version.
  2. Restore the pre-upgrade backup of the state store (Backup & recovery).
  3. Roll the image/package back to the matching prior version.
  4. On SQLite the restore sentinel detects the restored DB and arms recovery — clear it with kneo-dash recover --reconcile (supply the access map + a connection decision). On Postgres, arm/clear recovery manually per the runbook.

This is why step 1 of every upgrade is a backup: without a pre-upgrade backup, a schema you can't downgrade leaves no clean way back. The recovery/rollback path is exercised in CI (test_recovery_drill.py).

Version-specific notes

  • kneo-serv floors. Some features need a recent platform and degrade gracefully below the floor — the platform compatibility table is the reference (dash pins a kneo-client range, not a serv version).
  • Config additions. New releases may add KNEO_DASH_* settings with safe defaults; the environment reference lists every one (a CI parity check keeps it complete).