Protect the jellyfin-config PVC (library metadata, plugins, config XML)
with daily restic backups to the new Ceph RGW config-backup bucket.
- Add a k8up.io Schedule: daily backup (02:00), weekly prune (Sun 03:00,
keep 14 daily/8 weekly/12 monthly) and weekly check (Sun 04:00)
- Source S3 creds from the cephrgw BucketAccess Secret and the restic
repo password from Vault via a VaultStaticSecret (kv path
kubernetes/namespace/jellyfin/default/k8up-restic)
- Add the namespace VaultAuth (default role/SA) VSO needs to sync it
- Mount the reflected vault-ca-cert into the restic pods so restic trusts
the internal unkin.net CA on s3.ceph.unkin.net
- Wire the new files into the jellyfin kustomization
Give the jellyfin backup user a second bucket so k8up can store restic
backups of the jellyfin-config PVC alongside the existing CNPG barman
bucket (one user, two buckets).
- Add a jellyfin-config-backup Bucket owned by the existing
cnpg-jellyfin-backup ObjectStoreUser
- Add a read-write BucketAccess emitting jellyfin-config-backup-s3 with
the S3 creds k8up consumes
- Wire the new file into the jellyfin kustomization
Separate tv and movies onto their own volumes so sonarr/radarr can each
mount and manage their library individually later, and move media storage
off cephfs-raid6-retain onto cephfs-raid5-delete.
- Remove single jellyfin-media PVC (RWX, cephfs-raid6-retain)
- Add jellyfin-media-tv and jellyfin-media-movies PVCs (RWX, cephfs-raid5-delete, 500Gi each, expandable)
- Mount tv read-only at /media/tv and movies read-only at /media/movies in the statefulset
- Update kustomization resources to reference the two new PVCs
Turn the single-replica jellyfin-ha app into a proper high-availability
deployment so the fork's Redis-coordinated distributed transcoding and
PostgreSQL main database can actually be exercised.
- Replace the Deployment with a 2-replica StatefulSet for stable pod
identity; set JELLYFIN_INSTANCE_ID from metadata.name (the fork's Redis
transcode-lease owner id), add soft podAntiAffinity and a PDB
minAvailable 1.
- Move the main Jellyfin DB to PostgreSQL via a CloudNativePG trio
(3-instance Cluster, PgBouncer Pooler, Ceph RGW barman backups) mirroring
the litellm pattern; an init container writes database.xml selecting the
fork's Jellyfin-PostgreSQL provider and the DSN is composed from the
CNPG-generated app secret pointed at the pooler.
- Share /config on an RWX cephfs PVC across replicas; keep /cache per-pod
via a volumeClaimTemplate.
- Fix the transcode mount to the fork's real path /config/transcodes on the
RWX PVC (raid5) so a surviving pod can resume the segments of the pod it
takes over.
- Add Intel iGPU hardware transcoding via the gpu.intel.com/i915 device
plugin resource plus render/video supplemental groups.
- Switch the Service to sessionAffinity ClientIP to reduce transcode churn.
- Disable UDP auto-discovery. Library scans still run on every replica; a
single-scanner leader election is a planned follow-up.
Deploys the jellyfin-ha fork (git.unkin.net/unkin/jellyfin-ha) to au-syd1
via ArgoCD, under a dedicated media AppProject/ApplicationSet rather than
extending platform.
- New media AppProject + media-apps ApplicationSet (watches
apps/overlays/*/jellyfin); registered in the argocd kustomizations
- apps/base/jellyfin: namespace, deployment (single replica to start),
service, in-namespace Redis (transcode session store), gateway + httproute
at jellyfin.k8s.syd1.au.unkin.net
- Storage: RWO config (cephrbd), RWX transcode scratch and RWX media
library (cephfs) per the HA fork's pod-takeover requirement
- au-syd1 overlay