# Seerr — family request portal (watch.nook.family) # Init container ensures Jellyfin connection is always configured from git. # If settings.json has no Jellyfin apiKey (e.g. after reset), it is restored from the ConfigMap. --- apiVersion: v1 kind: ConfigMap metadata: name: seerr-defaults namespace: media data: jellyfin.json: | { "name": "Jellyfin", "ip": "jellyfin.media.svc.cluster.local", "port": 8096, "useSsl": false, "urlBase": "", "externalHostname": "https://jellyfin.nook.family", "jellyfinForgotPasswordUrl": "", "libraries": [], "serverId": "87e202a4e9ad49d1bf73927f714fbce6", "apiKey": "35e87cb67e3a4b908678ba9a257d2571" } --- apiVersion: apps/v1 kind: Deployment metadata: name: overseerr namespace: media labels: app: overseerr spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: overseerr template: metadata: labels: app: overseerr spec: initContainers: # Restore Jellyfin connection config if it was cleared (e.g. after pod restart with bad key) - name: restore-jellyfin-config image: node:22-alpine command: - sh - -c - | SETTINGS=/app/config/settings.json DEFAULTS=/defaults/jellyfin.json if [ ! -f "$SETTINGS" ]; then echo "No settings.json — creating with Jellyfin defaults" echo "{\"jellyfin\": $(cat $DEFAULTS)}" > $SETTINGS exit 0 fi KEY=$(node -e "try{const d=require('fs').readFileSync('$SETTINGS','utf8'); console.log(JSON.parse(d).jellyfin?.apiKey||'')}catch(e){console.log('')}") if [ -z "$KEY" ]; then echo "Jellyfin apiKey missing — restoring from defaults" node -e " const fs=require('fs'); const s=JSON.parse(fs.readFileSync('$SETTINGS','utf8')); s.jellyfin=JSON.parse(fs.readFileSync('$DEFAULTS','utf8')); fs.writeFileSync('$SETTINGS', JSON.stringify(s,null,2)); console.log('Restored Jellyfin config'); " else echo "Jellyfin config present, skipping restore" fi volumeMounts: - name: config mountPath: /app/config - name: seerr-defaults mountPath: /defaults containers: - name: overseerr image: seerr/seerr:latest env: - name: TZ value: "America/Chicago" ports: - containerPort: 5055 volumeMounts: - name: config mountPath: /app/config resources: requests: memory: 256Mi cpu: 100m limits: memory: 1Gi cpu: 500m livenessProbe: httpGet: path: /api/v1/status port: 5055 initialDelaySeconds: 30 periodSeconds: 30 readinessProbe: httpGet: path: /api/v1/status port: 5055 initialDelaySeconds: 15 periodSeconds: 10 volumes: - name: config persistentVolumeClaim: claimName: overseerr-config - name: seerr-defaults configMap: name: seerr-defaults --- apiVersion: v1 kind: Service metadata: name: overseerr namespace: media spec: selector: app: overseerr ports: - name: http port: 5055 targetPort: 5055 type: ClusterIP