From 2709e79455cdd7b827e96013dcb1805f380c5a40 Mon Sep 17 00:00:00 2001 From: dtoro Date: Sat, 4 Jul 2026 22:00:46 +0200 Subject: [PATCH] jellyfin: VAAPI HW accel + Authentik SSO + resource bump (2026-07-04) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Upgraded 10.11.8 → 10.11.11, enabled VAAPI (Radeon 760M) - Bumped to 4 cores / 8 GiB RAM / 1 GiB swap - SSO-Auth plugin v4.0.0.4 with Authentik OIDC - Removed Caddy forward-auth gate (incompatible with SSO plugin) - Updated container doc with full SSO architecture + pitfalls --- containers/101-jellyfin.md | 121 ++++++++++++++++++++++++++++++++++++- inventory.yaml | 5 ++ 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/containers/101-jellyfin.md b/containers/101-jellyfin.md index b374805..7386985 100644 --- a/containers/101-jellyfin.md +++ b/containers/101-jellyfin.md @@ -1,14 +1,17 @@ # 101 — `jellyfin` -Media server: serves the movies / TV / anime / music / audiobooks / podcasts libraries from `/mnt/library` to LAN clients. +Media server: serves the movies / TV / anime / music libraries from `/mnt/library` to LAN clients. Hardware transcoding via AMD Radeon 760M VAAPI. Authentik SSO via OIDC. ## At a glance - **Hostname:** `jellyfin` - **IP:** `192.168.8.206` - **Privilege:** **unprivileged** + idmap (so it can write to the `media` group on `/mnt/library`) -- **Resources:** 2 cores / 4 GiB RAM / 16 GiB rootfs +- **Resources:** 4 cores / 8 GiB RAM / 1 GiB swap / 16 GiB rootfs +- **GPU:** `/dev/dri/renderD128` (AMD Radeon 760M, RDNA 3) passed via `dev0` in LXC config - **Mounts:** `/mnt/library` ↔ `/mnt/library` - **Public hostname:** [`media.hubris.network`](../infrastructure/dns.md) → [caddy](121-caddy.md) → `:8096` +- **Version:** Jellyfin 10.11.11 (apt package, Ubuntu 24.04 noble repo) +- **FFmpeg:** jellyfin-ffmpeg7 7.1.4 ## Service / port map @@ -16,6 +19,106 @@ Media server: serves the movies / TV / anime / music / audiobooks / podcasts lib | -------- | ------ | ----- | | jellyfin | `:8096` | HTTP (caddy terminates TLS) | +## Hardware acceleration (VAAPI) + +GPU is passed through to the LXC via `dev0: /dev/dri/renderD128,gid=993` in +`/etc/pve/lxc/101.conf`. The `jellyfin` user is in the `render` (GID 993) and +`video` groups inside the container. + +Encoding settings (`/etc/jellyfin/encoding.xml`): +- `HardwareAccelerationType`: `vaapi` +- `VaapiDevice`: `/dev/dri/renderD128` +- `EnableHardwareEncoding`: `true` +- `AllowHevcEncoding`: `true` +- `AllowAv1Encoding`: `true` +- `EnableTonemapping`: `true` +- `HardwareDecodingCodecs`: h264, hevc, vc1, vp9, av1 +- `EnableThrottling`: `true` +- `EnableSegmentDeletion`: `true` + +Trickplay (`/etc/jellyfin/system.xml`): +- `EnableHwAcceleration`: `true` +- `EnableHwEncoding`: `true` + +## Authentik SSO (OIDC) + +Jellyfin uses the [SSO-Auth plugin](https://github.com/9p4/jellyfin-plugin-sso) +v4.0.0.4 for Authentik OIDC login. No Caddy forward-auth gate — the SSO plugin +handles auth directly via OIDC redirect flow. + +### Architecture + +``` +User → media.hubris.network → Caddy (TLS, no forward-auth) → Jellyfin :8096 + ↓ + Login page with "Sign in with Authentik" button + ↓ (click) + /sso/OID/start/Authentik + ↓ (302 redirect) + auth.hubris.network OIDC + ↓ (login) + /sso/OID/redirect/Authentik?code=...&state=... + ↓ + Jellyfin SSO plugin validates token → logged in +``` + +### Components + +1. **SSO-Auth plugin** — installed at `/var/lib/jellyfin/plugins/SSO-Auth_4.0.0.4/` + - Config: `/var/lib/jellyfin/plugins/configurations/SSO-Auth.xml` + - Provider name: `Authentik` + - OIDC endpoint: `https://auth.hubris.network/application/o/jellyfin/` + - `SchemeOverride`: `https` (required — without it, plugin generates + `http://` redirect URIs that Authentik rejects) + - `EnableAuthorization`: `false` (prevents plugin from overwriting admin + permissions on each SSO login — see + [jellyfin-sso-plugin](../devops/homelab-authentik-admin/references/jellyfin-sso-plugin.md)) + - `OidScopes`: `["email"]` (openid+profile added by default by the plugin; + must be non-null or `OidChallenge()` throws `ArgumentNullException`) + +2. **Authentik OIDC provider** — `Provider for Jellyfin` (PK 6) + - Client ID: `vt61t5Y2ZVtN6l3QjitkBvwUJjFKvSyl4TDBXcJx` + - Redirect URI: `https://media.hubris.network/sso/OID/redirect/Authentik` + - Application slug: `jellyfin` + +3. **SSO button injection** — `/usr/share/jellyfin/web/sso-inject.js` + - Injected via `