--- apiVersion: apps/v1 kind: Deployment metadata: name: sonarr namespace: arrstack spec: replicas: 1 strategy: # RWO config PVC + single stateful SQLite DB: never run two pods at once. type: Recreate selector: matchLabels: app: sonarr template: metadata: labels: app: sonarr spec: securityContext: # LinuxServer images init as root via s6 then step down to PUID/PGID. # fsGroup makes the shared CephFS group-writable for that user; # OnRootMismatch avoids a recursive chown of the whole media tree. fsGroup: 1000 fsGroupChangePolicy: OnRootMismatch initContainers: # Enforce the Vault-sourced API key in /config/config.xml before the app # starts. Vault is source of truth (override bootstrap): the key is minted # in Vault, synced by VSO into the sonarr-apikey Secret, and written here. # Runs as root to fix ownership; touches only the element. - name: apikey-init image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/library/busybox:1.37.0 imagePullPolicy: IfNotPresent securityContext: runAsUser: 0 env: - name: API_KEY valueFrom: secretKeyRef: name: sonarr-apikey key: apitoken command: - sh - -c - | set -eu case "$API_KEY" in "" | *[!0-9a-fA-F]*) echo "apikey-init: API_KEY missing or not hex; refusing" >&2 exit 1 ;; esac CFG=/config/config.xml if [ ! -f "$CFG" ]; then printf '\n %s\n\n' "$API_KEY" > "$CFG" elif grep -q '' "$CFG"; then sed -i "s|[^<]*|${API_KEY}|" "$CFG" else sed -i "s||\n ${API_KEY}|" "$CFG" fi chown 1000:1000 "$CFG" chmod 600 "$CFG" echo "apikey-init: enforced from Vault" resources: requests: cpu: 50m memory: 32Mi limits: cpu: 200m memory: 64Mi volumeMounts: - name: config mountPath: /config containers: - name: sonarr image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/linuxserver/sonarr:4.0.19 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8989 protocol: TCP env: - name: PUID value: "1000" - name: PGID value: "1000" - name: TZ value: Australia/Sydney livenessProbe: httpGet: path: /ping port: http initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /ping port: http initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 resources: requests: cpu: 100m memory: 256Mi limits: cpu: "1" memory: 1Gi volumeMounts: - name: config mountPath: /config - name: media-tv mountPath: /media/tv volumes: - name: config persistentVolumeClaim: claimName: sonarr-config - name: media-tv persistentVolumeClaim: claimName: media-tv