- Shell 100%
| .gitignore | ||
| plex-backup.service | ||
| plex-backup.sh | ||
| plex-backup.timer | ||
| README.md | ||
plex-backup
Automated backup script for Plex Media Server, designed to run on Linux as a
systemd timer. Backs up critical Plex data (preferences, plug-ins, databases),
optionally stops Plex during the copy to ensure SQLite consistency, and can sync
archives offsite to Backblaze B2 via rclone.
What gets backed up
By default the script captures the following paths inside PLEX_DATA_DIR:
| Path | Contents |
|---|---|
Preferences.xml |
Server settings |
Plug-ins/ |
Installed plug-ins |
Plug-in Support/Preferences/ |
Plug-in configuration |
Plug-in Support/Databases/ |
Plug-in databases |
The Metadata/ directory (cover art, artwork cache) is excluded by default
because it is large and fully regenerable. Uncomment the relevant line in
plex-backup.sh to include it.
Requirements
- Linux with
systemd - Bash 4+
tar,gzip(standard on any Linux distro)rclone— only required if offsite B2 sync is enabled
Installation
1. Copy the script
sudo cp plex-backup.sh /usr/local/sbin/plex-backup.sh
sudo chmod 700 /usr/local/sbin/plex-backup.sh
2. Install the systemd units
sudo cp plex-backup.service /etc/systemd/system/
sudo cp plex-backup.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now plex-backup.timer
3. Verify the timer is active
systemctl status plex-backup.timer
systemctl list-timers plex-backup.timer
Configuration
All options are environment variables with sensible defaults. Override them by
editing the Environment= lines in plex-backup.service, or export them in
your shell for one-off runs.
| Variable | Default | Description |
|---|---|---|
PLEX_DATA_DIR |
/var/lib/plexmediaserver/Library/Application Support/Plex Media Server |
Path to the Plex data directory |
BACKUP_DIR |
/var/backups/plex |
Where local archives are written |
KEEP_DAYS |
14 |
Days of local archives to retain |
STOP_PLEX |
true |
Stop Plex during copy for DB consistency |
PLEX_SERVICE |
plexmediaserver |
systemd service name for Plex |
COMPRESS |
true |
gzip the .tar archive |
B2_REMOTE |
(empty) | rclone remote path — enables B2 sync when set (e.g. b2:my-bucket/plex-backups) |
B2_KEEP_DAYS |
30 |
Days of archives to retain on B2 |
Example service override
[Service]
Environment=BACKUP_DIR=/mnt/nas/plex-backups
Environment=KEEP_DAYS=30
Environment=B2_REMOTE=b2:my-bucket/plex-backups
Environment=B2_KEEP_DAYS=60
Schedule
The timer fires daily at 03:00 with up to 10 minutes of random jitter
(RandomizedDelaySec=10min) to avoid thundering-herd issues on multi-machine
setups. Persistent=true means a missed run (e.g. the machine was off) will
execute on next boot.
To change the schedule, edit OnCalendar in plex-backup.timer. See
man systemd.time for the calendar syntax.
Offsite sync (Backblaze B2)
Set B2_REMOTE to an rclone remote path to upload each archive to B2 after
the local backup completes. rclone must be installed and the remote
pre-configured (rclone config).
# Quick test
sudo B2_REMOTE=b2:my-bucket/plex-backups /usr/local/sbin/plex-backup.sh
B2 retention is controlled independently from local retention via B2_KEEP_DAYS.
Archives older than that threshold are deleted from the remote after each
successful upload.
Running manually
sudo /usr/local/sbin/plex-backup.sh
Or trigger via systemd (logs go to the journal):
sudo systemctl start plex-backup.service
journalctl -u plex-backup.service -f
Archive format
Archives are written to BACKUP_DIR with the name:
plex-backup_YYYYMMDD_HHMMSS.tar.gz
Each archive contains a single plex/ directory tree mirroring the selected
paths from PLEX_DATA_DIR.
Restore
# Stop Plex
sudo systemctl stop plexmediaserver
# Extract into a temp location and inspect
sudo tar -xzf /var/backups/plex/plex-backup_20260101_030012.tar.gz -C /tmp/plex-restore
# Copy files back (adjust paths as needed)
sudo cp -a /tmp/plex-restore/plex/Preferences.xml \
"/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/"
# Restart Plex
sudo systemctl start plexmediaserver
Logs
Output goes to the systemd journal under the identifier plex-backup.
# Follow live
journalctl -u plex-backup.service -f
# Last run
journalctl -u plex-backup.service -n 50