Skip to content

iFredOS/plex-shield-migrator

Repository files navigation

plex-shield-migrator

Migrate a Plex Media Server database from a Synology NAS onto an NVIDIA Shield, while your media library stays on the NAS (mounted over SMB). The Shield becomes the server (HW transcode, <10 W, always-on); the NAS goes back to being just a file server.

You keep everything: all libraries, watch history, collections, and your custom artwork — and the server keeps the NAS's machine identity, so every Plex client reconnects seamlessly with no re-pairing.

Companion project: once you're up and running, keep the server fast and safe with plex-maintenance-toolkit — recommended Plex settings for a NAS-mounted library, a mount-checked trash emptier, and nightly-maintenance notifications.

Status: validated end-to-end on a DS918+ → Shield Pro (2019, Android 11) migration — the real-world failures encountered along the way shaped each guard in this tool.

Why not just rsync the data dir?

That's the obvious approach and it's a trap. This tool exists because of what goes wrong:

  • rsync chokes on Plex's Metadata/ tree — hundreds of thousands of tiny files send rsync's incremental recursion into a stall. We use a single tar stream instead.
  • The system sqlite3 can't touch Plex's database — Plex uses ICU collation; only Plex's own Plex SQLite binary can run the path remap without corrupting indexes.
  • A flaky USB drive silently corrupts everything — a drive that drops off the bus mid-write trashes the exFAT metadata. The tool health-checks the drive first and refuses to proceed if it isn't reliable.
  • Skipping the clean eject corrupts the copy — pulling an exFAT drive that wasn't sync'd + unmounted sets the dirty bit (the Shield then hangs on a filesystem check) and risks unflushed data. The tool's final step is a flush + clean eject, and the DB is proven on-disk with PRAGMA integrity_check.

How it works

   NAS (source)                          USB (transport)            Shield (destination)
   ┌──────────────────────┐   cp + tar   ┌────────────────┐  move   ┌────────────────────┐
   │ Plex DB + Metadata   │ ───────────► │ Android/data/  │ ──────► │ Plex starts off USB│
   │ /volume1/Media (34TB)│              │  .../Databases │         │ media via SMB mount│
   └──────────────────────┘              └────────────────┘         └────────────────────┘
        stays on NAS  ◄───────────────── SMB ──────────────────────  /storage/IDISKSTATION

The media never moves. Only Plex's application data (DB + artwork, a few GB) is copied to the USB the Shield boots from. The DB's media paths are rewritten /volume1/Media → /storage/IDISKSTATION/Media so every title Direct Plays immediately, no rescan.

Requirements

  • Synology NAS with the Plex Media Server package (provides Plex SQLite) and exFAT Access.
  • An NVIDIA Shield running the Plex Media Server (SMB) app, with ADB-over-WiFi enabled.
  • A healthy USB drive (formatted exFAT). Format it on a Mac/PC, then health-test it (./migrate.sh health does a write+readback md5 — a cheap drive that drops off the bus mid-write will silently corrupt your data).
    • macOS: diskutil eraseDisk ExFAT PLEX MBR /dev/diskN
    • Plex stores tens of thousands of tiny files. macOS defaults to a large 128 KB exFAT cluster, which roughly doubles on-disk usage and slows the copy. For a dedicated drive, prefer a smaller cluster: sudo newfs_exfat -c 32768 -v PLEX /dev/rdiskNs1 (32 KB), or format on Windows/Linux with a small allocation unit.
  • A workstation with adb + curl for the post-boot verification.

Usage

  1. Configure. Copy config/migrate.confconfig/migrate.conf.local and edit the paths/IPs for your setup.

  2. On the NAS, with the USB plugged in:

    ./migrate.sh health     # prove the drive is reliable first
    ./migrate.sh run        # stop NAS Plex → copy DB+art → remap → integrity_check → eject

    Or run the phases individually (preflight, stop, copy-db, copy-art, remap, eject).

  3. Move the USB to the Shield and power it on. Plex starts from the USB.

  4. On your workstation, verify the migration actually worked:

    ./verify-shield.sh      # identity + libraries + history + Direct Play path resolution
  5. Rollback at any time — the NAS Plex data is untouched:

    ./migrate.sh rollback   # restart the NAS Plex package

Layout

migrate.sh                  # NAS-side orchestrator (subcommands)
shield-control.sh           # Shield-side control over ADB — DETERMINISTIC, no screenshots
verify-shield.sh            # workstation-side post-boot acceptance check (ADB + Plex API)
tools/exfat-set-serial.py   # change a USB's exFAT volume serial in place (see below)
config/migrate.conf         # all environment-specific values
lib/common.sh               # logging / formatting helpers

Driving the Shield (no screenshots)

shield-control.sh controls the Shield with precise, repeatable adb commands — never screenshots or blind dpad navigation (which break across Plex versions). Commands: release-usb (unmount so you can remove the USB while the Shield stays awake), wait-up, launch, datadir (prints which dir Plex resolved — the fast way to catch a serial mismatch), verify, and up (the whole post-boot sequence). Note: poweroff uses reboot -p, which drops the Shield into deep standby where ADB cannot wake it — powering the Shield back on is a manual (remote) step.

USB serial mismatch (swapping drives)

Plex addresses a removable drive by its exFAT volume serial (e.g. /storage/FC5A-A76C/...). If you migrate the data onto a different USB drive, Plex keeps looking for the old serial, can't find its data, and falls back to first-run setup — with no way to re-point it (the setting lives past the first-run wall). Fix it by making the new drive report the old serial:

diskutil unmount /dev/diskNs1
sudo python3 tools/exfat-set-serial.py /dev/rdiskNs1 OLD-SERIAL            # dry-run
sudo python3 tools/exfat-set-serial.py /dev/rdiskNs1 OLD-SERIAL --commit   # write

It rewrites only the 4-byte volume serial + the exFAT boot checksum (main and mirrored backup) — no file data is touched. It self-validates its checksum against the drive's existing one before writing, and refuses on mismatch. Find the old serial in Plex's log: Kepler Server: [Storage] Application support dir is <path> (or shield-control.sh datadir).

Safety

  • The NAS Plex data directory is only read, never modified — rollback is just restarting the package.
  • Every destructive or irreversible step pauses for confirmation (--yes to skip in automation).
  • Don't decommission the NAS Plex until verify-shield.sh passes and you've watched a few days of playback.

License

MIT — see LICENSE.

About

Deterministic toolkit to migrate Plex Media Server from a Synology NAS to an NVIDIA Shield (media stays on the NAS over SMB): DB+path remap, exFAT serial relabel, ADB control, mount-checked safe empty-trash, Pushover maintenance alerts.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors