--- apiVersion: apps/v1 kind: Deployment metadata: name: prowlarr namespace: arrstack spec: # Active-active: the -unkin2 fork keeps all state in the shared Postgres # (arrstack-postgres) and coordinates via Postgres advisory locks, so N # replicas run concurrently behind the prowlarr Service. RollingUpdate is safe # — no SQLite, no RWO lock. replicas: 3 strategy: type: RollingUpdate selector: matchLabels: app: prowlarr template: metadata: labels: app: prowlarr spec: securityContext: # Fork image has no USER (runs as root by default); pin it to a non-root # UID and group-write the shared RWX CephFS /config. OnRootMismatch # avoids a recursive chown of the whole volume. runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 fsGroupChangePolicy: OnRootMismatch initContainers: # Gate the app on its own Postgres database+role being reachable, instead # of relying on ArgoCD sync-waves (which deadlock if apps aren't Healthy). # waitfordb reads the PG* env as a libpq fallback, so the password never lands in argv. - name: wait-for-db image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/waitfordb:v0.1.0 env: - name: WAITFORDB_TIMEOUT value: 5m - name: WAITFORDB_SSLMODE value: disable - name: PGHOST value: arrstack-postgres-rw.arrstack.svc.cluster.local - name: PGPORT value: "5432" - name: PGDATABASE value: prowlarr-main - name: PGUSER valueFrom: secretKeyRef: name: prowlarr-db key: username - name: PGPASSWORD valueFrom: secretKeyRef: name: prowlarr-db key: password resources: requests: cpu: 10m memory: 32Mi limits: cpu: 100m memory: 64Mi containers: - name: prowlarr image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/prowlarr:v2.6.2-unkin5 imagePullPolicy: IfNotPresent command: - /app/Prowlarr args: - -nobrowser - -data=/config # Required: bypass the single-instance guard so multiple replicas # can share one /config. Cross-replica safety is the Postgres layer, # not a local lock file. - -nosingleinstancecheck ports: - name: http containerPort: 9696 protocol: TCP envFrom: - configMapRef: name: prowlarr-env env: - name: Prowlarr__Postgres__User valueFrom: secretKeyRef: name: prowlarr-db key: username - name: Prowlarr__Postgres__Password valueFrom: secretKeyRef: name: prowlarr-db key: password - name: Prowlarr__Auth__ApiKey valueFrom: secretKeyRef: name: prowlarr-apikey key: apitoken # Backup object store (shared arrstack-backups Ceph RGW bucket, # per-app key prefix). Routes the periodic config+DB zip backups off # the ephemeral /config so any replica can write and restore them. # Consumed by the -unkin3+ image; older images ignore these unknown # config keys. Creds Secret minted by cephrgw-operator. - name: Prowlarr__BackupS3__Endpoint valueFrom: secretKeyRef: name: arrstack-backups-s3 key: S3_ENDPOINT - name: Prowlarr__BackupS3__AccessKey valueFrom: secretKeyRef: name: arrstack-backups-s3 key: AWS_ACCESS_KEY_ID - name: Prowlarr__BackupS3__SecretKey valueFrom: secretKeyRef: name: arrstack-backups-s3 key: AWS_SECRET_ACCESS_KEY - name: Prowlarr__BackupS3__Bucket value: arrstack-backups - name: Prowlarr__BackupS3__Prefix value: prowlarr - name: Prowlarr__BackupS3__ForcePathStyle value: "true" - name: Prowlarr__BackupS3__CaCertPath value: /etc/ssl/vault-ca/ca.crt livenessProbe: httpGet: path: /prowlarr/ping port: http initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /prowlarr/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: vault-ca mountPath: /etc/ssl/vault-ca readOnly: true volumes: - name: config emptyDir: {} # Estate CA for validating the Ceph RGW (s3.ceph.unkin.net) TLS cert. - name: vault-ca secret: secretName: vault-ca-cert items: - key: ca.crt path: ca.crt