What it is
Plex is the streaming server that indexes my media library and serves it to clients — Plex apps on the phone, the TV, the browser. Libraries point at a single mount that's backed by rclone-zurg, which is itself a FUSE view onto the upstream media catalogue.
Why I run it
The shape of "what I want to watch tonight" doesn't map cleanly onto streaming-service catalogues. Plex gives me a single library across movies, TV, and anime that doesn't disappear when a licensing deal lapses; the apps are good enough that the experience competes with the major streamers; the social features (shared libraries) are a nice incidental.
The thing I like operationally is that Plex doesn't actually own the files. The mount it reads from is provided by rclone-zurg. I can swap that pipeline out without touching Plex. The server is just an index plus a player — the heavy work happens behind the FUSE mount.
How I use it
Three libraries, all pointed at the host-managed media mount: a movies library, an anime library, and a catch-all library that exposes the broader upstream catalogue. The Plex apps connect over the local network and over Tailscale; transcoding happens server-side when the client needs it.
Behind the scenes, three companion services round out the experience: Tautulli for watch statistics, Overseerr for requests, and AniBridge to sync watch progress to AniList for anime.
The non-obvious win is the transcoder temporary directory setting. Plex's nightly "extensive media analysis" task generates BIF files (the thumbnails you see when you scrub the timeline), and by default that scratch data lands on the LXC's small rootfs. Setting Transcoder Temp Dir to a path on the larger data mount moved ~50 GB of nightly scratch writes off the rootfs and onto the disk that's actually sized for them.
Setup notes
- Host: the media LXC on the laptop node. Co-located with the rest of the
media-kitchenstack (Tautulli, Overseerr, Riven, Seanime, AniBridge) and the host-level rclone mount they all consume. - Reverse proxy: yes, with websockets enabled.
- Backups: PBS captures the LXC. The Plex database is moderately heavy; the actual media files live behind the FUSE mount and follow the upstream provider's durability model rather than my backup schedule.
- Update cadence: manual. Image pinned. A defensive
com.centurylinklabs.watchtower.enable=falselabel is set, on top of the monitor-only mode — belt and suspenders for a service I really don't want auto-updating mid-stream.
Runbook
- Healthy looks like: every client connects, libraries show content, scrubbing the timeline shows thumbnails (BIF files generated correctly), nothing is buffering on local network.
- Clients connect to a stale IP: Plex's
customConnectionsfield inPreferences.xmlis sticky and persists across host changes. There's no web UI for this — edit the file inside the container, restart Plex. - Playback slow or episode runtimes wrong after a host move: stale metadata cache from the previous host, not a network problem. Per-library, run "Empty Trash" and "Refresh All Metadata" with "Replace existing matches" toggled on. Re-pulls fresh metadata and fixes both symptoms.
- Media mount is empty inside the container but populated on the host: classic FUSE stale-FD problem. The host's rclone mount restarted at some point, which created a new FUSE file descriptor; the container's bind mount still references the old one. Fix: restart the consumer containers so they pick up the new FD. There's a helper script that does this for the whole stack at once.
- Where logs live: Plex's web UI under Status → Logs for app-level events;
docker logs plexon the host for the container itself.