Sanitized mirror from private repository - 2026-04-20 01:32:01 UTC
This commit is contained in:
179
docs/services/individual/jellyfin-olares.md
Normal file
179
docs/services/individual/jellyfin-olares.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# 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
|
||||
```bash
|
||||
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)
|
||||
```bash
|
||||
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:
|
||||
```bash
|
||||
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
|
||||
```yaml
|
||||
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:
|
||||
|
||||
```yaml
|
||||
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-np` NetworkPolicy — 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/gpu` resources; 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
|
||||
```bash
|
||||
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
|
||||
```bash
|
||||
# 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
|
||||
Reference in New Issue
Block a user