Kubernetes Deployment
This guide covers deploying Jellyfin on Kubernetes using the official Helm chart.
Prerequisites
- Kubernetes cluster (v1.19+)
- Helm 3.x installed
kubectlconfigured for your cluster- Sufficient storage for media and configuration
- Ingress controller (e.g. traefik) for external access (required for this tutorial, see official docs for alternatives)
Installation
1. Add Helm Repository
helm repo add jellyfin https://jellyfin.github.io/jellyfin-helm
helm repo update
2. Custom Installation
For complete installation instructions and configuration options, see the official Jellyfin Helm chart repository.
Create a values.yaml file for customization:
# values.yaml
replicaCount: 1
image:
pullPolicy: IfNotPresent
persistence:
config:
enabled: true
size: 5Gi
storageClass: ''
media:
enabled: true
size: 100Gi
storageClass: ''
ingress:
enabled: true
className: 'traefik'
hosts:
- host: jellyfin.example.com
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 500m
memory: 1Gi
nodeSelector: {}
tolerations: []
affinity: {}
Install with custom values:
helm install jellyfin jellyfin/jellyfin -f values.yaml
Configuration Options
Service Types
This guide covers ClusterIP service type (default) for internal access only, with external access via ingress controller. Alternatives include LoadBalancer and NodePort services.
Persistence
Using Existing Persistent Volume Claims
persistence:
config:
enabled: true
existingClaim: 'jellyfin-config-pvc'
media:
enabled: true
existingClaim: 'jellyfin-media-pvc'
Creating New PVCs via Helm
persistence:
config:
enabled: true
size: 5Gi
storageClass: 'fast-ssd'
media:
enabled: true
size: 100Gi
storageClass: 'slow-hdd'
Ingress
Basic Ingress Configuration
ingress:
enabled: true
className: 'traefik'
hosts:
- host: jellyfin.example.com
paths:
- path: /
pathType: Prefix
Advanced Ingress with TLS
ingress:
enabled: true
className: 'traefik'
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: default-jellyfin-buffering@kubernetescrd
hosts:
- host: jellyfin.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: jellyfin-tls
hosts:
- jellyfin.example.com
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: jellyfin-buffering
namespace: default
spec:
buffering:
maxRequestBodyBytes: 0
Accessing Jellyfin
Port Forwarding (Development)
kubectl port-forward svc/jellyfin 8096:8096
Access at: http://localhost:8096
External Access
Once ingress is configured, access Jellyfin at your configured domain (e.g., https://jellyfin.example.com).
Monitoring
Health Checks
The chart includes readiness and liveness probes:
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 5
periodSeconds: 5
Metrics
Enable Prometheus metrics if available:
metrics:
enabled: true
serviceMonitor:
enabled: true
Troubleshooting
Common Issues
- Permission Denied: Ensure proper security context for media access
- Storage Issues: Verify persistent volume claims are bound
- Network Access: Check service type and ingress configuration
Debug Commands
# Check pod status
kubectl get pods -l app.kubernetes.io/name=jellyfin
# View logs
kubectl logs -f deployment/jellyfin
# Check service
kubectl get svc jellyfin
# Describe pod for events
kubectl describe pod -l app.kubernetes.io/name=jellyfin
Upgrading
# Update repository
helm repo update
# Upgrade installation
helm upgrade jellyfin jellyfin/jellyfin
# Check upgrade status
helm status jellyfin
Uninstalling
# Remove Helm release
helm uninstall jellyfin
# Clean up persistent volumes (if needed)
kubectl delete pvc -l app.kubernetes.io/name=jellyfin
Advanced Configuration
Hardware Acceleration
For GPU acceleration, add device access and security context:
securityContext:
privileged: true
resources:
limits:
gpu.intel.com/i915: 1
# or nvidia.com/gpu: 1
extraVolumes:
- name: dri
hostPath:
path: /dev/dri
extraVolumeMounts:
- name: dri
mountPath: /dev/dri
Multiple Media Sources
Mount multiple media sources using additional volumes:
volumes:
- name: movies
persistentVolumeClaim:
claimName: movies-pvc
- name: tv
persistentVolumeClaim:
claimName: tv-pvc
volumeMounts:
- name: movies
mountPath: /movies
- name: tv
mountPath: /tv
Custom Environment Variables
extraEnvVars:
- name: JELLYFIN_PublishedServerUrl
value: 'https://jellyfin.example.com'
- name: JELLYFIN_CACHE_DIR
value: '/cache'
For more configuration options, see the Jellyfin Helm chart documentation.