Your media is not the thing at risk. You have the files, and if the server disappears you still have them.
What you cannot get back is everything the server learned: who your users are, what everyone watched, where they got to, every piece of metadata you corrected by hand. That lives in one directory, and copying it is the whole job.
What to back up
The config directory
Users, watch history, resume points, settings, metadata, plugin configuration. This is the irreplaceable part.
Not the cache directory
Artwork that can be downloaded again and transcodes that are already disposable. It is large and it is worth nothing.
Not your media
Back it up, certainly, but that is a separate job with separate economics, and it is not what this page is about.
Where the config directory is depends on how you installed:
| Platform | Location |
|---|---|
| Docker | Whatever you mapped to /config |
| Windows | %ProgramData%\Jellyfin\Server |
| macOS | ~/.local/share/jellyfin |
| Debian and Ubuntu | /var/lib/jellyfin, with config in /etc/jellyfin |
| Synology and QNAP | The folder you mapped when you created the container |
Note
On Docker this is the reason to map config to a directory you chose rather
than letting Docker manage a volume. A path you can see is a path you can copy.
Stop the server first
The important part, and the one most people skip.
Jellyfin keeps its data in SQLite databases. Copying a database while it is being written produces a file that looks fine and is subtly corrupt, and you find out when you try to restore it, which is the worst possible moment.
docker compose stop jellyfin
# copy the config directory
docker compose start jellyfin
A home server is idle most of the night. Thirty seconds of downtime at four in the morning costs nothing and is the difference between a backup and a file.
Careful
A backup taken from a running server is not a backup. It will restore, it will appear to work, and the database may be damaged in ways that surface weeks later. Stop the server.
A script that does it
#!/usr/bin/env bash
set -euo pipefail
CONFIG=/srv/jellyfin/config
DEST=/mnt/backups/jellyfin
STAMP=$(date +%Y-%m-%d)
docker compose -f /srv/jellyfin/docker-compose.yml stop jellyfin
tar czf "$DEST/jellyfin-$STAMP.tar.gz" -C "$(dirname "$CONFIG")" "$(basename "$CONFIG")"
docker compose -f /srv/jellyfin/docker-compose.yml start jellyfin
# Keep a month.
find "$DEST" -name 'jellyfin-*.tar.gz' -mtime +30 -delete
set -euo pipefail is doing real work in there: without it, a failed copy is
followed cheerfully by the deletion of your old backups.
Run it nightly from cron, or from your NAS’s own scheduler.
Put it somewhere else
A backup on the same disk as the server protects you from exactly one thing: deleting something by accident. It does not protect you from the disk failing, which is the thing that actually happens.
The usual arrangement, in increasing order of paranoia: another disk in the same machine, another machine in the house, and somewhere outside the house.
For a config directory, which is small, off-site is cheap. It compresses well and a typical home server’s config is measured in hundreds of megabytes rather than gigabytes.
Prove it works
An untested backup is a belief, not a backup. Test it once, now, and then once a year.
The honest test is a restore onto different hardware, which also tells you how long a real recovery takes.
- Install Jellyfin somewhere else, or in a second container on a different port.
- Stop it.
- Replace its config directory with your backup.
- Start it.
- Sign in with your own account and check the watch history is there.
If you can sign in and your resume list looks right, the backup is real.
Tip
Write down what you did, including the paths and the commands. You will be doing this next under time pressure, having not thought about it for a year, and past you is the only person who can help.
Restoring for real
- Install the same major version of Jellyfin. Restoring into an older version than the backup came from does not work.
- Stop it.
- Replace the config directory with the backup.
- Check the file ownership, especially in Docker. A restored directory owned by root and a container running as user 1000 is a server that will not start.
- Start it.
- Check the library paths still point at where your media actually is, which may have changed if you are restoring onto different hardware.
Back up the compose file too
Not part of the config directory, and it is how the server is assembled. Your
docker-compose.yml, or the equivalent notes about how you installed and what
you mounted where.
It is a small text file and it is the difference between a twenty-minute restore and an afternoon of remembering.
A minimum that is better than nothing
If you do nothing else on this page:
docker compose stop jellyfin
tar czf ~/jellyfin-config-backup.tar.gz -C /srv/jellyfin config
docker compose start jellyfin
Then copy that file somewhere else. It takes two minutes and it covers the overwhelming majority of what goes wrong.