6.4 KiB
Jellyfin on Olares
Service Overview
| Property | Value |
|---|---|
| Host | olares (192.168.0.145) |
| Platform | Olares Marketplace (K3s) |
| Namespace | jellyfin-vishinator |
| Image | docker.io/beclab/jellyfin-jellyfin:10.11.6 |
| LAN Access | http://192.168.0.145:30096 |
| Olares Proxy | https://7e89d2a1.vishinator.olares.com |
| GPU | NVIDIA RTX 5090 Max-Q (24GB) — hardware transcoding |
Purpose
Jellyfin media server on Olares with NVIDIA GPU hardware transcoding and NFS media from Atlantis. Replaces a previous Plex attempt (Plex had issues with Olares proxy auth and indirect connections from desktop apps).
Architecture
Atlantis NAS (192.168.0.200)
└─ NFS: /volume1/data/media
└─ mounted on olares at /mnt/atlantis_media (fstab)
└─ hostPath volume in Jellyfin pod at /media (read-only)
Olares K3s cluster
└─ jellyfin-vishinator namespace
└─ Deployment: jellyfin (2 containers)
├─ jellyfin (main app, port 8096)
└─ olares-envoy-sidecar (Olares proxy)
Deployment Patches
The Jellyfin app was installed from the Olares marketplace, then patched with kubectl patch for:
1. NFS Media Mount
kubectl patch deployment jellyfin -n jellyfin-vishinator --type=json -p '[
{"op":"add","path":"/spec/template/spec/volumes/-","value":{"name":"atlantis-media","hostPath":{"path":"/mnt/atlantis_media","type":"Directory"}}},
{"op":"add","path":"/spec/template/spec/containers/0/volumeMounts/-","value":{"name":"atlantis-media","mountPath":"/media","readOnly":true}}
]'
2. GPU Access (NVIDIA runtime + env vars)
kubectl patch deployment jellyfin -n jellyfin-vishinator --type=json -p '[
{"op":"add","path":"/spec/template/spec/REDACTED_APP_PASSWORD","value":"nvidia"},
{"op":"add","path":"/spec/template/metadata/annotations","value":{"applications.app.bytetrade.io/gpu-inject":"true"}},
{"op":"replace","path":"/spec/template/spec/containers/0/resources/limits","value":{"cpu":"4","memory":"8Gi"}},
{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"NVIDIA_VISIBLE_DEVICES","value":"all"}},
{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"NVIDIA_DRIVER_CAPABILITIES","value":"all"}}
]'
Important: Do NOT request nvidia.com/gpu or nvidia.com/gpumem resources. HAMI's vGPU interceptor (libvgpu.so injected via /etc/ld.so.preload) causes ffmpeg to segfault (exit code 139) during CUDA transcode operations (especially tonemap_cuda). By omitting GPU resource requests, HAMI doesn't inject its interceptor, and Jellyfin gets direct GPU access via the nvidia runtime class.
3. HAMI Memory Override (if GPU resources are requested)
If you do need HAMI GPU scheduling (e.g., to share GPU fairly with LLM workloads), override the memory limit:
kubectl patch deployment jellyfin -n jellyfin-vishinator --type=json -p '[
{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"CUDA_DEVICE_MEMORY_LIMIT_0","value":"8192m"}}
]'
Note: This alone does NOT fix the segfault — libvgpu.so in /etc/ld.so.preload is the root cause.
LAN Access
Olares's envoy proxy adds ~100ms per request, causing buffering on high-bitrate streams. Direct LAN access bypasses this.
NodePort Service
apiVersion: v1
kind: Service
metadata:
name: jellyfin-lan
namespace: jellyfin-vishinator
spec:
type: NodePort
externalIPs:
- 192.168.0.145
selector:
app: jellyfin
ports:
- port: 8096
targetPort: 8096
nodePort: 30096
name: jellyfin-web
Calico GlobalNetworkPolicy
Olares auto-creates restrictive NetworkPolicies (app-np) that block external LAN traffic and cannot be modified (admission webhook reverts changes). A Calico GlobalNetworkPolicy bypasses this:
apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
name: allow-lan-to-jellyfin
spec:
order: 100
selector: app == 'jellyfin'
types:
- Ingress
ingress:
- action: Allow
source:
nets:
- 192.168.0.0/24
This is the correct approach for LAN access on Olares. Alternatives that don't work:
- Patching
app-npNetworkPolicy — webhook reverts it - Adding custom NetworkPolicy — webhook deletes it
- iptables rules on Calico chains — Calico reconciles and removes them
Jellyfin Settings
Hardware Transcoding
In Dashboard > Playback > Transcoding:
- Hardware acceleration: NVIDIA NVENC
- Hardware decoding: All codecs enabled (H264, HEVC, VP9, AV1, etc.)
- Enhanced NVDEC: Enabled
- Hardware encoding: Enabled
- HEVC encoding: Allowed
- AV1 encoding: Allowed (RTX 5090 supports AV1 encode)
- Tone mapping: Enabled (bt2390, HDR→SDR on GPU)
Library Paths
| Library | Path |
|---|---|
| Movies | /media/movies |
| TV Shows | /media/tv |
| Anime | /media/anime |
| Music | /media/music |
| Audiobooks | /media/audiobooks |
NFS Mount
# /etc/fstab on olares
192.168.0.200:/volume1/data/media /mnt/atlantis_media nfs rw,async,hard,intr,rsize=131072,wsize=131072 0 0
Performance
- Sequential read: 180-420 MB/s (varies by cache state)
- More than sufficient for multiple 4K remux streams (~100 Mbps each)
Known Issues
- Patches lost on Olares app update — if Jellyfin is updated via the marketplace, the NFS mount and GPU patches need to be re-applied
- HAMI vGPU causes ffmpeg segfaults — do NOT request
nvidia.com/gpuresources; use nvidia runtime class without HAMI resource limits - Olares proxy buffering — use direct LAN access (
http://192.168.0.145:30096) for streaming, not the Olares proxy URL - GPU shared with Ollama — both Jellyfin and Ollama access the full 24GB VRAM without HAMI partitioning; heavy concurrent use (4K transcode + large model inference) may cause OOM
Maintenance
Check status
kubectl get pods -n jellyfin-vishinator
kubectl exec -n jellyfin-vishinator deploy/jellyfin -c jellyfin -- nvidia-smi
Re-apply patches after update
Run the kubectl patch commands from the Deployment Patches section above.
Check transcoding
# Is ffmpeg using GPU?
kubectl exec -n jellyfin-vishinator deploy/jellyfin -c jellyfin -- nvidia-smi
# Look for ffmpeg process with GPU memory usage
# Check transcode logs
kubectl logs -n jellyfin-vishinator deploy/jellyfin -c jellyfin | grep ffmpeg | tail -5
Last Updated: 2026-04-03