Files
serverAppConfigs/serverAppConfigs-docs/Dankserver/Plex.md
T
Frank 327e78b950 docs(vault): destroy the dead weight — 53 pages and the change diary
The vault was 155 pages / 31,210 lines, most of it measurement ledgers for
payloads that no longer run. A throughput figure for a runtime nobody operates is
not a record: AI moves faster than the vault, so the number is wrong before
anyone reads it, and a wrong number in a runbook gets believed. Per the new
purpose test in `AGENTS.md` → *Documentation Policy*, it is destroyed.

Gone (`.AGENTTRASH/20261019-destruction/`, KILL-LIST.txt is the manifest):
- the `frank-medium` endpoint and its five era pages, `frank-npu`, FastFlowLM,
  the ikllama/kingjones/dealign/frank-redo eras, the ling/swift15/freetoken/ubatch
  campaign pages, qwen3.8 spec-matrix and strix-optimizations, the two
  "Running Qwen3.6 …" pages;
- the whole `Pipeline Parallelism/` folder (no live script passes a pipeline flag)
  and the multi-device/x4-pair/hybrid/offload experiment pages;
- every vLLM page — no vLLM endpoint exists on this fleet;
- `LLM/deployment.md` (`Architecture/Deployment Flow.md` is the test-referenced
  owner) and the external surveys (SGLang, Lemonade, llama.cpp forks/diff,
  self-hosted app census, the TTS survey) that were obsolete by construction;
- `log.md`, 2,380 lines. Git holds the chronology; a causal law belongs to the
  page that owns the thing it governs, never to a diary.

Survivors: 101 pages, 17,542 lines, 0 OKF violations, 0 unresolved links. Eras
tables keep the window, payload, runtime, reason and rollback pointer; the rate
columns are blanked. The live shapes stay verbatim — those numbers are what the
deployer and `models.yml` consume.
2026-10-19 10:56:37 -07:00

4.5 KiB

type, description, tags, timestamp
type description tags timestamp
reference Plex Media Server is a **containerized media server on Dankserver**: a podman
dankserver
plex
2026-09-15

Plex

Plex Media Server is a containerized media server on Dankserver: a podman quadlet (plex.service) under the systemd user generator, generated from dankserver/plex/quadlet/plex.container. It shares the host with a second live media server, Jellyfin (jellyfin.service, listening on 8096); both serve from the same read-only Entropy Volume mount.

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.4.10903-e5521bd8c-ls325 (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 fleet rootless model — container root maps to the dank user (1000:1000); the deployer chowns the data root on first cutover
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 two R9700s stay dedicated to frank-archon
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. The one metadata change: rootless podman cannot map the real host uid 997, so the fleet model applies — container root runs as the dank user, and the deployer adopts the data root with chown -R 1000:1000 on first cutover (rollback chowns it back).

Cutover & rollback

  • First deploy stops and masks plexmediaserver.service (never disable — on these hosts disable deletes the unit file), chowns /var/lib/plexmediaserver to 1000:1000, then starts the quadlet; the deployer blocks until /identity answers on 32400.
  • Rollback lever while masked: systemctl --user stop plex.service && sudo chown -R 997:984 /var/lib/plexmediaserver && sudo systemctl unmask plexmediaserver.service && sudo systemctl start plexmediaserver.service (ownership-only churn — zero bytes ever moved).
  • 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) — 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.
  4. Cold container boot is slow. PMS pre-binds 32400 and empty-replies while the HTTP layer finishes loading; the first boot of a years-old library took ~10 minutes (2026-09 cutover). The deployer gate now allows 600 s before failing; later boots are much faster (warm page cache).