J7 — Upgrading
Rendered from spec at76d46f3 (2026-10-25) · its source · Edit this page
Status: Accepted · Audience: Operator
The journey
$ lemonfiber update stack --check
sonarr 4.0.15 → 4.0.16 patch
jellyfin 10.10.3 → 10.11.11 minor · via 10.10.7 · release notes ↗
prowlarr 1.28.1 → 2.0.0 MAJOR · release notes ↗
⚠ Sonarr, Jellyfin and Prowlarr migrate their databases on first
start of a new version. Returning to the current versions
afterwards is not possible.
A backup will be taken automatically before updating.
The one genuinely irreversible operation
The *arrs migrate their SQLite schema on first start, and there is no downgrade path. Pull a newer image, find it unusable, and you cannot simply revert — the database has already been rewritten in a format the previous binary refuses to open.
A move within a major can migrate too. Jellyfin 10.10 to 10.11 stays inside major 10, so it is a minor update, and it still rewrites the database: a 10.10.5 or later server refuses to start on it afterwards, and upstream migrates only from 10.10.7, so the update passes through it (ADR-0028). The size of the jump and whether it can be undone are two separate facts, and the update states both.
By default this is a one-word command with no warning. Stating it in advance
(E1-R3) is the single highest-value thing this journey does.
Why versions are pinned at all
Nothing changes because time passed (E1-R1). An update happens when the
operator decides one should.
The alternative — floating tags — means an unrelated pull can jump six months
across a dozen services simultaneously, with no way back and no way to tell which
of twelve changes broke things.
Backup is a precondition, not an offer
$ lemonfiber update stack
Backing up… ✓ 41 MB · config-2026-07-24T19-12.tar
sonarr 4.0.15 → 4.0.16 ✓ healthy in 6s
prowlarr 1.28.1 → 2.0.0 ✗ failed to start
Update halted. jellyfin was not updated.
prowlarr is not healthy — see logs below.
Two properties doing real work:
- If the backup fails, the update does not proceed (
E1-R5). The safety net is a precondition. - Services update one at a time, health verified between each (
E1-R6). A single failure is diagnosable; twelve simultaneous ones are not. The run halts rather than continuing into a half-migrated stack (E1-R7).
What recovery looks like from here
| Situation | Path |
|---|---|
| Service updated, no migration | Rollback — repin and restart (E4-R3) |
| Service migrated its database | Restore from the pre-update backup. Rollback is refused, with the reason stated (E4-R5) |
| Update never started | Nothing to undo |
lemonfiber offers only the path that can actually work.
Where it goes wrong
| Situation | Behaviour |
|---|---|
| Registry unreachable | Update check fails; stack untouched |
| Disk too full to pull | Detected before pulling — a failed pull from a full disk is confusing (E1-R11) |
| Downloads active | Reported, with an option to wait (E1-R12) |
| Only one service needs updating | Update just that one (E1-R13) |
| Operator wants to stay put indefinitely | Fully supported. lemonfiber must not nag (E1-R14) |
| Locally edited stack files | Never silently overwritten; a diff is shown (E1-R9) |
Related
- J6 Recovery — when an update goes wrong
- E1 Stack updates · E2 Self-update
- A5 Migration — why adoption refuses to downgrade