mipo
Guide

Operations: Upgrade

An evaluator-facing overview of the in-place upgrade flow and its safety model. This is not the operational procedure.

Operators: use the runbook in your release bundle

The step-by-step upgrade procedure is the file docs/operations/upgrade.md in the mipo source checkout or the release bundle your operator received (public publication of the repository is pending). That file is the authoritative reference. Follow it instead of this page.

The upgrade flow

  1. Pull the new images (does not touch running containers).
  2. Preflight gate: mipo.sh deploy runs the migrator preflight FAIL-CLOSED before any ingress or app change — DB connectivity, schema drift, disk free, app-version downgrade. Backup recency and scanner protocol compatibility are reported as informational lines only and never block the deploy (backup recency: owner decision 2026-07-08; scanner protocol compatibility: reverse-DNS R1a, 2026-09-12). A preflight failure leaves the previous version serving, the proxy untouched and the database unchanged.
  3. Quiesce: the watchdog (autoheal) is stopped first so it cannot restart what the deploy stops, then the schema-writing app roles (manager, ingest, dispatcher, maintenance) are stopped so no old writer races the migration. The database stays up.
  4. Edge: TLS storage is migrated and the proxy chain (socket proxy and Traefik) is force-recreated. This happens after the preflight gate on purpose, so a failed preflight never mutates ingress.
  5. Migrate: forward-only schema migrations run with the app quiesced.
  6. Roll out: the new images start and the app comes back up.
  7. Scanner fleet: upgrade every scanner and resolver host with upgrade.sh (see below). Until a host is upgraded past a raised protocol floor it cannot claim work.

When should you take a backup?

A deploy never wipes data by itself — it applies forward-only (additive) migrations. A fresh backup is strongly advised for the one risky case: mutating the schema of an install that already holds data — but it is a deployer judgment call, not a gate; preflight reports the backup's age without blocking.

  • In-place upgrade (new version over an existing install): Strongly advised — preflight reports the newest backup’s age but does not block the upgrade on it (owner decision 2026-07-08)
  • Fresh / Day-0 install (empty cluster): Not required — the gate auto-skips (nothing to protect)
  • Wipe and reinstall (reset --all): Not required — you are deliberately destroying data
  • Restore from a bundle: You already hold the backup
  • Force an upgrade through anyway: MIPO_DEPLOY_PREFLIGHT=0 (break-glass; logged loudly)

Upgrading the scanner fleet

A server deploy never touches scanner hosts: the manager does not push binaries, so every scanner and resolver is upgraded by an operator, after the server deploy, with upgrade.sh. The script verifies the new binary's SHA-256 and Ed25519 signature with the same fail-closed checks as the installer, keeps the host's identity and configuration (/var/lib/mipo-scanner, /etc/mipo-scanner.env, the unit file), and stops, swaps and restarts every role installed on the host in one pass. Never re-run install.sh on a provisioned host — it always provisions, which needs a fresh one-time token and re-creates the scanner as if it were new.

There is no compatibility window: the scanner wire protocol has a floor equal to the current version, so a release that raises the protocol leaves every older scanner unable to claim work (the claim is refused with 409 SCANNER_PROTOCOL_UNSUPPORTED, and the dispatcher stops publishing jobs to it) until the host is upgraded. Upgrade hosts only after the server deploy that raises the floor, never before — a newer scanner is refused by an older server in exactly the same way. Admin > Release lists each scanner's reported protocol version and flags the ones that need an upgrade. The procedure, including the exact upgrade.sh invocation and rollback, is docs/operations/scanner-upgrade.md in the source checkout or release bundle; the install overview is at Scanner: Linux systemd service.