diff --git a/serverAppConfigs-docs/Dankserver/Plex.md b/serverAppConfigs-docs/Dankserver/Plex.md index 8d64ac9..3988067 100644 --- a/serverAppConfigs-docs/Dankserver/Plex.md +++ b/serverAppConfigs-docs/Dankserver/Plex.md @@ -1,42 +1,56 @@ # Plex -Plex Media Server is the **native (non-container) media server running on -Dankserver**. It is the only media server actually listening on this host: -`plexmediaserver.service` is an OS-package systemd unit -(`/usr/lib/systemd/system/plexmediaserver.service`), enabled and -running — verified live 2026-08-29. Jellyfin, by contrast, is a research +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 (live-verified 2026-08-29) +## Facts | Item | Value | |------|-------| -| Runtime | native systemd service (`plexmediaserver.service`), **not** a podman quadlet | -| State | enabled + running (up since 2026-08-21) | -| Port | `32400/tcp` on `0.0.0.0` | -| Updates | OS package manager (`apt`) — **not** `scripts/deploy.sh`; the deploy flow never touches this service | -| GPU | RTX 3090 present; NVENC hardware transcode needs the NVIDIA driver + Plex Pass (PMS gates HW transcoding behind the paid tier) | +| 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 it is not a quadlet +## Why in-place bind mounts -Plex ships as a distro package with its own systemd unit and update -channel; the repo's boot-persistence rule is satisfied by the native unit -(it is `enabled`, so it survives reboot — verify with -`systemctl is-enabled plexmediaserver`). Converting it to a container later -is a migration, not a config edit: the PMS database (`/var/lib/plexmediaserver`) -and its claim-token identity would move with it. +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 `:32400` +- **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 @@ -45,10 +59,12 @@ and its claim-token identity would move with it. ## Gotchas -1. **Do not benchmark on it blind.** PMS transcodes contend with the LLM - fleet for the same GPU; stop the service (or pin it to CPU - transcoding) before benchmark runs, per the Benchmarking Policy. -2. **Updates are OS-level** — `apt`/`aptly`, not `deploy.sh`; a deploy - plan that names `plex` is a bug in the plan. +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). + `.env`, never in this repo (secret rules apply). The token lives in + `Preferences.xml` inside the RW data bind, preserved by the migration. diff --git a/serverAppConfigs-docs/Dankserver/Tautulli.md b/serverAppConfigs-docs/Dankserver/Tautulli.md index 31c08be..c10604e 100644 --- a/serverAppConfigs-docs/Dankserver/Tautulli.md +++ b/serverAppConfigs-docs/Dankserver/Tautulli.md @@ -1,29 +1,34 @@ # Tautulli Tautulli is the statistics, monitoring, and notification companion for -Plex Media Server. On Dankserver it runs as a **snap** -(`snap.tautulli.tautulli.service`, verified live 2026-08-29) — a third -runtime style on this host alongside podman quadlets and the native Plex -unit. It listens on `8181/tcp` on all interfaces. +Plex Media Server. On Dankserver it runs as a **podman quadlet** +(`tautulli.service`) under the systemd **user** generator, generated from +`dankserver/tautulli/quadlet/tautulli.container` — migrated from the snap +(2026-09; the snap carried zero config, so the cutover was a fresh install). **Host:** Dankserver — **Depends on:** [[Plex]] (it is pointless without -it; it talks to PMS over `:32400` using the same claim token clients use). +it; it talks to PMS over the appnet at `http://plex:32400`). -## Facts (live-verified 2026-08-29) +## Facts | Item | Value | |------|-------| -| Runtime | snap (`snap.tautulli.tautulli.service`) — not a quadlet, not an OS package | -| State | running; snaps self-start at boot (no unit to enable) | -| Port | `8181/tcp` on `0.0.0.0` | -| Updates | `snap refresh tautulli` — the snap store channel is the update path, not `deploy.sh` | +| Runtime | podman quadlet, `tautulli.service` (user manager) — migrated from snap `snap.tautulli.tautulli.service` | +| Image | `lscr.io/linuxserver/tautulli:v2.18.1-ls242` (pinned; verified == the ghcr `latest` manifest digest at pin time) | +| Data root | `/home/dank/Containers/tautulli` bind-mounted as `/config` (fresh at cutover — the snap's `/var/snap/tautulli/common` was empty) | +| Identity | `UsernsMode=host` + `PUID=1000 PGID=1000` | +| Port | `8181/tcp` published on `0.0.0.0` | +| Network | `dankserver_appnet`, alias `tautulli` | +| PMS URL | `http://plex:32400` — seeded into `config.ini` by the deployer on first start | +| Health | in-container `python3` probe of `http://localhost:8181/home`, 30 s interval / 3 retries | +| Deploy | `./scripts/deploy.sh dankserver --service tautulli` | | Docs | https://github.com/Tautulli/Tautulli/wiki | ## What it buys this fleet - Concurrent-stream dashboard and history: who is watching what, right now, - on which client — the only tool that answers "is the 3090 busy - transcoding for someone?" without SSHing in. + on which client — the only tool that answers "is the CPU busy transcoding + for someone?" without SSHing in. - Notifications: library updates, download completions, player watch sessions — wire them to whatever notifier the fleet standardizes on (Discord/ntfy/Telegram are all one dropdown away). @@ -37,9 +42,12 @@ it; it talks to PMS over `:32400` using the same claim token clients use). anyone on the LAN can read the whole watch history. Fine while LAN-only; if a public vhost is ever pointed at it, put the Authentik + Anubis chain in front first ([[Authentik]], [[Anubis]]). -2. **Snap confinement.** Logs live under `/var/snap/tautulli/common`, not - the conventional `/config` path quadlet services use — Grafana/Loki - log-shipping paths must account for it ([[Loki]], [[Alloy]]). -3. If Plex is ever containerized or migrated, Tautulli's claim-token - handling survives (it stores its own copy) but re-verify the PMS URL - and port in its settings immediately after the migration. +2. **First boot shows the setup wizard** — expected pre-token behavior; the + wizard also answers 200 on `/home`, so the health gate stays green before + any token exists. Enter the PMS claim token through the web UI after + cutover; it is stored inside the config bind, never in this repo. +3. **Snap-era paths are gone.** Logs and config live under the config bind + (`/home/dank/Containers/tautulli/...`), not `/var/snap/tautulli/common` — + Grafana/Loki log-shipping paths must account for it ([[Loki]], [[Alloy]]). +4. **Updates are commit-driven** — pin a new `-ls` tag in the unit file and + redeploy; never run `:latest`.