# Plex Plex Media Server is the **containerized media server on Dankserver**: a podman quadlet (`plex.service`) under the systemd **user** generator, generated from `dankserver/plex/quadlet/plex.container`. It is the only media server actually listening on this host. Jellyfin, by contrast, is a research brief on this host, not a running service (see [[Jellyfin]]). **Host:** Dankserver — **Ports:** 32400/tcp (PMS web + API), 32400 is the only port PMS needs for client streaming; LAN clients connect directly, public traffic can be fronted by Caddy like every other vhost. ## Facts | Item | Value | |------|-------| | Runtime | podman quadlet, `plex.service` (user manager) — migrated from the native `plexmediaserver.service` OS-package unit (2026-09) | | Image | `lscr.io/linuxserver/plex:1.43.3.10896-cb3ebc72d-ls322` (pinned; verified == the ghcr `latest` manifest digest at pin time) | | Data root | `/var/lib/plexmediaserver` bind-mounted **in place** as `/config` (RW) — the migration moved zero bytes | | Media | `/mnt/entropy` mounted at the same absolute path **read-only** — every library path in the PMS database stayed valid, zero re-scan | | Identity | `UsernsMode=host` + `PUID=997 PGID=984` — container writes land owned 997:984, byte-compatible with the former native unit | | Port | `32400/tcp` published on `0.0.0.0` — zero client reconfiguration | | Network | `dankserver_appnet`, alias `plex`; Tautulli reaches it at `http://plex:32400` | | GPU | none by decision — CPU decode only; the RTX 3090 stays dedicated to `frank-default-small` | | Deploy | `./scripts/deploy.sh dankserver --service plex` | | Docs | https://support.plex.tv | ## Why in-place bind mounts The migration moved zero bytes: the container bind-mounts the native data root where it already lived, and the media archive re-mounts at `/mnt/entropy` inside the container, so every absolute library path in the PMS database keeps resolving. `UsernsMode=host` + `PUID=997/PGID=984` makes the container's file identity indistinguishable from the old service's — no chown, no re-scan. Rollback is byte-safe at any time before decommission. ## Cutover & rollback - First deploy stops and **masks** `plexmediaserver.service` (never `disable` — on these hosts `disable` deletes the unit file), then starts the quadlet; the deployer blocks until `/identity` answers on 32400. - Rollback lever while masked: `systemctl --user stop plex.service && sudo systemctl unmask plexmediaserver.service && sudo systemctl start plexmediaserver.service`. - Decommission (`sudo apt-get -y purge plexmediaserver`) only after explicit operator sign-off. ## Integration points - **Caddy:** Plex is exempt from the Anubis bot challenge (plain-HTTP legacy clients cannot solve JS challenges) — see [[Anubis]] "Exempt by construction". - **Tautulli** ([[Tautulli]]) is the companion: it polls PMS on the appnet for statistics and notifications and makes no sense without Plex. - **Auth wall:** if a public vhost is ever pointed at Plex, put the Authentik outpost + Anubis chain in front of it like every other guarded vhost ([[Authentik]], [[Caddy]]); direct `:32400` exposure to the LAN is unauthenticated by design (Plex owns its own auth via claim tokens). ## Gotchas 1. **Do not benchmark on it blind.** Transcoding is CPU-only now but still contends with the LLM fleet's host-RAM expert streaming; stop the service before benchmark runs, per the Benchmarking Policy. 2. **Updates are commit-driven, not apt.** The OS package is retired at cutover; upgrading PMS means pinning a new `-ls` tag in the unit file and redeploying — never run `:latest`. 3. The claim token is the identity of this server; document it in the host `.env`, never in this repo (secret rules apply). The token lives in `Preferences.xml` inside the RW data bind, preserved by the migration.