diff options
| author | Paul Buetow <paul@buetow.org> | 2026-01-30 23:01:22 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-01-30 23:01:22 +0200 |
| commit | 8ec2c7fe34625a34c098d18278bd83589da7042f (patch) | |
| tree | a70e48cff52e138d274673a345e5b43a1710df8a | |
| parent | 153507db10ad37d7da1720975916b1af1c09ef7d (diff) | |
Add jellyfin deployment
Amp-Thread-ID: https://ampcode.com/threads/T-019c10b2-ea57-752e-818e-33a56d69d9fa
Co-authored-by: Amp <amp@ampcode.com>
| -rw-r--r-- | f3s/argocd-apps/services/jellyfin.yaml | 28 | ||||
| -rw-r--r-- | f3s/jellyfin/Justfile | 38 | ||||
| -rw-r--r-- | f3s/jellyfin/README.md | 86 | ||||
| -rw-r--r-- | f3s/jellyfin/helm-chart/Chart.yaml | 5 | ||||
| -rw-r--r-- | f3s/jellyfin/helm-chart/templates/.gitignore | 2 | ||||
| -rw-r--r-- | f3s/jellyfin/helm-chart/templates/ingress.yaml | 15 | ||||
| -rw-r--r-- | f3s/jellyfin/helm-chart/templates/persistent-volume.yaml | 28 | ||||
| -rw-r--r-- | f3s/jellyfin/values.yaml | 52 |
8 files changed, 254 insertions, 0 deletions
diff --git a/f3s/argocd-apps/services/jellyfin.yaml b/f3s/argocd-apps/services/jellyfin.yaml new file mode 100644 index 0000000..f24974e --- /dev/null +++ b/f3s/argocd-apps/services/jellyfin.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: jellyfin + namespace: cicd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: http://git-server.cicd.svc.cluster.local/conf.git + targetRevision: master + path: f3s/jellyfin/helm-chart + destination: + server: https://kubernetes.default.svc + namespace: services + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=false + retry: + limit: 3 + backoff: + duration: 5s + factor: 2 + maxDuration: 1m diff --git a/f3s/jellyfin/Justfile b/f3s/jellyfin/Justfile new file mode 100644 index 0000000..46848de --- /dev/null +++ b/f3s/jellyfin/Justfile @@ -0,0 +1,38 @@ +NAMESPACE := "services" +APP_NAME := "jellyfin" + +status: + @echo "=== Pods ===" + @kubectl get pods -n {{NAMESPACE}} | grep jellyfin + @echo "" + @echo "=== Services ===" + @kubectl get svc -n {{NAMESPACE}} | grep jellyfin + @echo "" + @echo "=== Ingress ===" + @kubectl get ingress -n {{NAMESPACE}} jellyfin-ingress + @echo "" + @echo "=== PVCs ===" + @kubectl get pvc -n {{NAMESPACE}} | grep jellyfin + @echo "" + @echo "=== ArgoCD Status ===" + @kubectl get application {{APP_NAME}} -n cicd -o jsonpath='Sync: {.status.sync.status}, Health: {.status.health.status}' 2>/dev/null && echo "" + +logs lines="100": + kubectl logs -n {{NAMESPACE}} -l app=jellyfin-server --tail={{lines}} -f + +port-forward port="8096": + @echo "Forwarding jellyfin to localhost:{{port}}" + kubectl port-forward -n {{NAMESPACE}} svc/jellyfin-server {{port}}:8096 + +sync: + @echo "Triggering ArgoCD sync..." + @kubectl annotate application {{APP_NAME}} -n cicd argocd.argoproj.io/refresh=normal --overwrite + @sleep 2 + @kubectl get application {{APP_NAME}} -n cicd -o jsonpath='Sync: {.status.sync.status}, Health: {.status.health.status}' && echo "" + +argocd-status: + argocd app get {{APP_NAME}} --core + +restart: + @echo "Restarting jellyfin server..." + kubectl rollout restart -n {{NAMESPACE}} deployment/jellyfin-server diff --git a/f3s/jellyfin/README.md b/f3s/jellyfin/README.md new file mode 100644 index 0000000..1cc9160 --- /dev/null +++ b/f3s/jellyfin/README.md @@ -0,0 +1,86 @@ +# Jellyfin Kubernetes Deployment + +This directory contains the Kubernetes configuration for deploying [Jellyfin](https://jellyfin.org/) - a free software media system that puts you in control of your media and data. + +## Architecture + +Jellyfin is a single-component deployment consisting of: +- **Server**: Main media server with web interface and API + +## Prerequisites + +1. **Create storage directory on the NFS server**: + ```bash + for host in f0 f1 f2; do + ssh paul@$host "doas mkdir -p /data/nfs/k3svolumes/jellyfin" + ssh paul@$host "doas chown -R 911:911 /data/nfs/k3svolumes/jellyfin/" + done + ``` + +## Deployment + +1. **Install the custom resources** (PVs, PVCs, ingress): + ```bash + just install-resources + ``` + +2. **Install Jellyfin using Helm** (or ArgoCD): + ```bash + just sync + ``` + +3. **Check deployment status**: + ```bash + just status + ``` + + Wait for all pods to be in `Running` state (may take a few minutes for image pulls). + +## Access + +Once deployed, Jellyfin will be available at: **https://jelly.f3s.buetow.org** + +Default setup instructions: +1. Navigate to the URL above +2. Complete the setup wizard on first access +3. Configure libraries and preferences + +## Storage + +Persistent storage is configured with: +- **Data**: Main configuration and metadata at `/data/nfs/k3svolumes/jellyfin` +- **Media**: Mount your media directories from other NFS sources as needed + +## Maintenance + +### Restart Jellyfin +```bash +just restart +``` + +### View logs +```bash +just logs +``` + +### Port forward for local access +```bash +just port-forward +``` + +### Uninstall (keeps data) +```bash +kubectl delete application jellyfin -n cicd +``` + +## Troubleshooting + +### Check pod logs +```bash +kubectl logs -n services -l app=jellyfin-server --tail=100 +``` + +### Verify persistent volumes +```bash +kubectl get pv,pvc -n services | grep jellyfin +``` diff --git a/f3s/jellyfin/helm-chart/Chart.yaml b/f3s/jellyfin/helm-chart/Chart.yaml new file mode 100644 index 0000000..bd2ca92 --- /dev/null +++ b/f3s/jellyfin/helm-chart/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: jellyfin-resources +description: Custom resources for Jellyfin deployment (PVs, PVCs, Ingress) +version: 0.1.0 +appVersion: "latest" diff --git a/f3s/jellyfin/helm-chart/templates/.gitignore b/f3s/jellyfin/helm-chart/templates/.gitignore new file mode 100644 index 0000000..8eeb559 --- /dev/null +++ b/f3s/jellyfin/helm-chart/templates/.gitignore @@ -0,0 +1,2 @@ +# Secrets should not be committed +*-secret.yaml diff --git a/f3s/jellyfin/helm-chart/templates/ingress.yaml b/f3s/jellyfin/helm-chart/templates/ingress.yaml new file mode 100644 index 0000000..de4b028 --- /dev/null +++ b/f3s/jellyfin/helm-chart/templates/ingress.yaml @@ -0,0 +1,15 @@ +# Jellyfin Traefik Ingress +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: jellyfin-ingress + namespace: services +spec: + entryPoints: + - web + routes: + - match: Host(`jelly.f3s.buetow.org`) + kind: Rule + services: + - name: jellyfin-server + port: 8096 diff --git a/f3s/jellyfin/helm-chart/templates/persistent-volume.yaml b/f3s/jellyfin/helm-chart/templates/persistent-volume.yaml new file mode 100644 index 0000000..bf16da6 --- /dev/null +++ b/f3s/jellyfin/helm-chart/templates/persistent-volume.yaml @@ -0,0 +1,28 @@ +# Jellyfin PersistentVolume - Configuration and metadata storage +apiVersion: v1 +kind: PersistentVolume +metadata: + name: jellyfin-pv +spec: + capacity: + storage: 50Gi + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + hostPath: + path: /data/nfs/k3svolumes/jellyfin + type: Directory +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: jellyfin-pvc + namespace: services +spec: + storageClassName: "" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 50Gi diff --git a/f3s/jellyfin/values.yaml b/f3s/jellyfin/values.yaml new file mode 100644 index 0000000..7e083c9 --- /dev/null +++ b/f3s/jellyfin/values.yaml @@ -0,0 +1,52 @@ +# Jellyfin Helm Chart Configuration +# Deploy to services namespace with persistent storage + +# Image configuration +image: + repository: jellyfin/jellyfin + tag: latest + pullPolicy: IfNotPresent + +# Persistence +persistence: + config: + enabled: true + type: pvc + existingClaim: jellyfin-pvc + mountPath: /config + size: 50Gi + +# Service configuration +service: + type: ClusterIP + port: 8096 + +# Ingress configuration +ingress: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: web + hosts: + - host: jelly.f3s.buetow.org + paths: + - path: / + pathType: Prefix + +# Resources +resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 2000m + memory: 2Gi + +# Node selector (if needed) +nodeSelector: {} + +# Tolerations (if needed) +tolerations: [] + +# Affinity rules (if needed) +affinity: {} |
