Upgrading MFConsole¶
How to move to a newer version, back up first, and roll back if something goes wrong. The exact steps differ by deployment type — check which one you're running before you start.
Before you upgrade: take a backup¶
If Cloud Backup (S3) is configured (Settings → Cloud Backup), the console already backs up its own database and configuration every night. Don't rely on one that might be up to a day stale for an upgrade you're about to do on purpose — trigger a fresh one first from Settings, and confirm it shows verified before continuing.
If Cloud Backup isn't configured yet, set it up before upgrading — see the Backup & Restore how-to. An upgrade without a backup in place has no safety net if it goes wrong.
Schema changes only ever add
MFConsole's database migrations only add columns and tables, never remove or rename them. That's what makes rolling back safe by default: older code simply ignores columns it doesn't know about, so you don't need to restore the database just to undo a code upgrade — only if the upgrade itself somehow behaved badly and you also want to discard data it wrote in between.
Single-host deployments¶
The default (Free-edition) install runs one console host with no HA components. This is the common case, and it's the simplest to upgrade.
Option A — the in-console "Update Now" button (Settings → System →
Updates). This pulls the new image and restarts app/worker/beat
automatically — you'll see a brief interruption while they restart, and
the page reloads once it's back. This only works on a registry-pull
install (the default); it's not available if you built the image from
source yourself.
Option B — re-run the installer from the directory you installed into:
Never re-extract into a new directory to update
Re-running the "deploy from scratch" steps in a second directory
reuses the same database volume (Compose names it after the directory,
always mfconsole) while generating a new database password —
Postgres only applies a password at volume creation, so the app
crash-loops on password authentication failed forever. Always cd
into your existing install directory and re-run install.sh there.
Rolling back a single-host deployment¶
Point compose.prod.yml's image reference back at the previous version
tag and re-run the compose up:
export MFCONSOLE_IMAGE=docker.io/mfconsole/kvm-manager:<previous-version>
docker compose -f docker-compose.yml -f compose.prod.yml --profile single pull
docker compose -f docker-compose.yml -f compose.prod.yml --profile single up -d
(podman compose in place of docker compose if you're on Podman.) Per
the note above, this is safe without touching the database unless the
version you're rolling back from did something non-additive to the schema
— check that release's changelog entry if you're unsure.
HA (3-node) deployments¶
There is no automated "Update Now" for an HA cluster yet — each host's
app-N/worker/beat needs pulling and recreating individually,
leaving the host currently holding the VIP for last so the console
only takes one brief interruption instead of two:
# on each non-VIP-holding host first, then the VIP holder last:
export MFCONSOLE_IMAGE=docker.io/mfconsole/kvm-manager:<new-version>
docker compose -f docker-compose.yml -f compose.prod.yml --profile ha pull
docker compose -f docker-compose.yml -f compose.prod.yml --profile ha up -d --no-deps --force-recreate app-N worker beat
(substitute app-1/app-2/app-3 for the host you're on). Verify each
host is healthy before moving to the next:
docker compose ps # every service Up/healthy
curl -sk https://127.0.0.1/ -o /dev/null -w '%{http_code}\n' # 200
Rolling back an HA deployment follows the same per-host procedure with the
previous version's MFCONSOLE_IMAGE.
Compute nodes after an upgrade¶
Some fixes only reach already-enrolled hypervisor nodes after a Repair Worker pass (Hosts → a node → Repair Worker) — the console doesn't yet detect on its own whether a node needs one. Check that release's changelog entry for an explicit call-out, and when in doubt, running Repair Worker after any upgrade is harmless even if it wasn't strictly needed.