New ADRs: - 0043: Cilium CNI and Network Fabric - 0044: DNS and External Access Architecture - 0045: TLS Certificate Strategy (cert-manager) - 0046: Companions Frontend Architecture - 0047: MLflow Experiment Tracking and Model Registry - 0048: Entertainment and Media Stack - 0049: Self-Hosted Productivity Suite - 0050: Argo Rollouts Progressive Delivery - 0051: KEDA Event-Driven Autoscaling - 0052: Cluster Utilities (Spegel, Descheduler, Reloader, CSI-NFS) - 0053: Vaultwarden Password Management README updated with table entries and badge count (53 total).
5.2 KiB
Entertainment and Media Stack
- Status: accepted
- Date: 2026-02-09
- Deciders: Billy
- Technical Story: Deploy a self-hosted media automation and streaming platform for the homelab
Context and Problem Statement
Self-hosting media services provides control over content libraries, avoids subscription costs for multiple streaming services, and integrates with the homelab's storage and networking infrastructure.
How do we deploy a complete media management pipeline — from content acquisition to streaming — with minimal manual intervention?
Decision Drivers
- Automated content discovery, download, and organization
- Single media library shared across all services
- Internal-only access (no public exposure)
- Minimal resource footprint per service
- Integration with NFS storage for large media libraries
Decision Outcome
Deploy the *arr stack (Sonarr, Radarr, Prowlarr, Bazarr) for automated media management plus Jellyfin for streaming, all sharing a single NFS-backed media volume.
Architecture
┌──────────────────────────────────────────────────────────────┐
│ DISCOVERY & INDEXING │
│ │
│ Prowlarr (indexer manager) │
│ ↓ syncs indexers to │
│ Sonarr (TV) + Radarr (Movies) │
│ ↓ sends requests to │
│ qbittorrent (download client) [suspended — pending VPN] │
│ ↓ downloads to │
│ /media (shared NFS volume) │
│ ↓ organizes into │
│ Sonarr/Radarr import + rename │
│ ↓ subtitle lookup via │
│ Bazarr (subtitle manager) │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ STREAMING │
│ │
│ Jellyfin (media server) │
│ ← reads from /media (shared NFS volume) │
│ ← transcodes to /config/transcodes (emptyDir) │
│ → streams to LAN clients (web, apps, DLNA) │
└──────────────────────────────────────────────────────────────┘
Components
| Component | Image | Purpose | Resources (req → limit) |
|---|---|---|---|
| Jellyfin | jellyfin/jellyfin:10.11.6 |
Media server & streaming | 100m/1Gi → —/4Gi |
| Sonarr | ghcr.io/onedr0p/sonarr:4.0.14.2938 |
TV series management | 50m/256Mi → —/1Gi |
| Radarr | ghcr.io/onedr0p/radarr:5.20.1.9773 |
Movie management | 50m/256Mi → —/1Gi |
| Prowlarr | ghcr.io/onedr0p/prowlarr:1.32.2.4987 |
Indexer aggregation | 50m/128Mi → —/512Mi |
| Bazarr | ghcr.io/onedr0p/bazarr:v1.5.1 |
Subtitle management | 50m/256Mi → —/1Gi |
| qbittorrent | ghcr.io/onedr0p/qbittorrent:5.0.4 |
Download client | Suspended |
All deployed via bjw-s app-template v4.6.2 in the entertainment namespace.
Storage Architecture
| Volume | StorageClass | Size | Access | Mounted By |
|---|---|---|---|---|
jellyfin-media |
nfs-slow |
500Gi | RWX | Jellyfin, Sonarr, Radarr, Bazarr |
| Config PVCs | longhorn |
2-10Gi | RWO | One per app |
| Transcodes | emptyDir |
— | — | Jellyfin only |
The shared jellyfin-media NFS volume is the key integration point — *arr apps write organized media files, Jellyfin reads and streams them.
Network Access
All services are internal-only via envoy-internal gateway at *.lab.daviestechlabs.io:
| Service | URL |
|---|---|
| Jellyfin | jellyfin.lab.daviestechlabs.io |
| Sonarr | sonarr.lab.daviestechlabs.io |
| Radarr | radarr.lab.daviestechlabs.io |
| Prowlarr | prowlarr.lab.daviestechlabs.io |
| Bazarr | bazarr.lab.daviestechlabs.io |
qbittorrent has a dedicated Cilium LoadBalancer VIP (10.0.0.210) for BitTorrent traffic, separate from the HTTP gateway.
Security
All *arr apps run as non-root (UID 568), with read-only root filesystem and all Linux capabilities dropped. qbittorrent is suspended pending VPN/Multus integration to ensure download traffic is routed through a VPN tunnel.