This lab reproduces, on a disposable machine, the guide how to upgrade Jellyfin 12 with Docker and keep a way back: you start from 10.11.11 installed as in the guide to installing Jellyfin with Docker, copy the config volume, jump to 12.0 and test the rollback. Everything you see in the terminal really ran, with the official jellyfin/jellyfin:10.11.11 and jellyfin/jellyfin:12.0 images.

Why you copy /config before you upgrade Jellyfin 12

12.0 rewrites the database on its first start, and the Jellyfin backup and restore documentation is clear about it: there is no downgrade mechanism. In the official image, data and config live together under /config, so that folder is the only thing you need to keep. The 12.0 release notes only support the direct jump from 10.10.7 or any 10.11.x.

How to back up a named volume

With Jellyfin stopped, a throwaway alpine:3 container mounts the jellyfin-config volume read-only and packs it with tar. It is the same pattern as the Docker volume backup and restore lab, and the article on Docker volumes and bind mounts explains the difference between volumes and bind-mounted folders. The Docker documentation on volumes describes the same technique.

What the lab’s rollback proves

Going back to the 10.11.11 tag without restoring the backup leaves a server that answers Healthy on /health and reports its version through the API, but whose log holds a fatal startup error. Restoring the tar.gz and starting 10.11.11 gives a log with no FTL lines and the same server ID. If you run Jellyfin on the latest tag, also read the article on Watchtower for automatic Docker updates: the official image on Docker Hub moves latest to 12.0, and an automatic update migrates with no backup first.

The lab does not cover the full library scan or third-party plugins, because the machine has no library and no users. Those steps, with their measured times, are in the written guide.

FAQ

Can I go back to Jellyfin 10.11 just by changing the image tag?

No. In this lab, 10.11.11 started on already migrated data answered Healthy on /health and reported its version through the API, but its log held a fatal error while starting the application. You have to restore the /config backup taken before migrating.

How do I check the Jellyfin version without logging in?

Query /System/Info/Public, which needs no authentication: curl -s http://localhost:8096/System/Info/Public | jq -r .Version. In the lab it returned 10.11.11 before the upgrade and 12.0.0 after it.

How do I back up if I use named volumes?

Stop Jellyfin and mount the volume in a helper container: docker run –rm -v jellyfin-config:/config:ro -v "$PWD":/backup alpine:3 tar -czf /backup/jellyfin-config.tar.gz -C / config. The restore is the same idea in reverse, with the volume mounted writable.

Do I need to run –mode MigrateSystem before starting 12.0?

No, the server migrates on startup anyway. Running it separately lets you read the result: in the lab it announced 18 CoreInitialisation migrations and 13 AppInitialisation ones. Since it exits 0 even when it fails, check that the log says Migrations have been applied and has no FTL lines.