Files
Frank 6bdfd2853e docs(vault): service and infrastructure pages stop restating endpoint facts
18 pages cut their per-endpoint shape, payload, port and window claims and
link [[frank-archon]] / [[frank-dragoon]] / [[frank-zealot]] instead. Several
of the cut claims had already drifted -- the stack page still described the
kingjones ROCmFP4 era on ROCmFPX, OpenWebUI carried the 27B/3-slot bench
narrative, Hermes named a retired max_model_len and the old service name, and
the OMP harness page's live-window block had drifted off frank-zealot's real
262,144 (it is now labelled a dated worked example whose authority is the
endpoint page).

Two facts gain a single owner instead of two: the up{job=~"frank-.*"} scope
lives in Infrastructure/Prometheus.md, and the blackbox/Anubis probe form in
Architecture/Stale Signal Audit.md, each cited from the other page.

Voice Packs and Frank TTS carried live-state claims that contradicted the
engine page's 2026-10-18 deploy record (nothing listening on 7772/8880, model
dir absent); they now point at the pages that own host state.
2026-10-19 00:56:02 -07:00

87 lines
4.5 KiB
Markdown

---
type: reference
description: "Plex Media Server is a **containerized media server on Dankserver**: a podman"
tags:
- dankserver
- plex
timestamp: 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) — 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.
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).