From 8847e20e0e352f35f88904534e0fc872730f863f Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sat, 22 Aug 2026 15:25:25 +1000 Subject: [PATCH] arrstack: provision shared Ceph RGW bucket for media assets Servarr MediaCover (posters/fanart) and backups currently live on each replica's local /config, which is an emptyDir - so covers a leader downloads are invisible to the other replicas behind the Service. Provision a shared S3 bucket to hold these assets instead. - Add an arrstack-media ObjectStoreUser + Bucket (cephrgw-operator), mirroring the CNPG backup pattern; the operator mints the arrstack-media-s3 credential Secret in-namespace, so no Vault KV seeding is required. - Wire the radarr Deployment to the bucket via Radarr__MediaCover__S3__* env (creds from the operator Secret, estate CA mounted for RGW TLS). Unknown to the current image and activated by the -unkin3+ MediaCover-S3 build; sonarr and prowlarr wiring follow. --- apps/base/arrstack/kustomization.yaml | 1 + apps/base/arrstack/media-bucket.yaml | 34 +++++++++++++++++++++ apps/base/arrstack/radarr/deployment.yaml | 37 +++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 apps/base/arrstack/media-bucket.yaml diff --git a/apps/base/arrstack/kustomization.yaml b/apps/base/arrstack/kustomization.yaml index 5015628..2f16ec7 100644 --- a/apps/base/arrstack/kustomization.yaml +++ b/apps/base/arrstack/kustomization.yaml @@ -9,6 +9,7 @@ resources: - pv-media-movies.yaml - pvc-media-tv.yaml - pvc-media-movies.yaml + - media-bucket.yaml - postgres - sonarr - radarr diff --git a/apps/base/arrstack/media-bucket.yaml b/apps/base/arrstack/media-bucket.yaml new file mode 100644 index 0000000..e9dd338 --- /dev/null +++ b/apps/base/arrstack/media-bucket.yaml @@ -0,0 +1,34 @@ +--- +# Shared Ceph RGW (S3) bucket for arrstack media assets (Servarr MediaCover +# posters/fanart and, later, application backups), provisioned by the in-estate +# cephrgw-operator. Moving these off each replica's local /config (an emptyDir) +# lets any radarr/sonarr/prowlarr replica serve covers and store backups without +# leader-local state. The operator mints the S3 credential Secret +# (arrstack-media-s3) in this namespace with keys AWS_ACCESS_KEY_ID, +# AWS_SECRET_ACCESS_KEY and S3_ENDPOINT, so no Vault KV seeding is required. +apiVersion: ceph.unkin.net/v1alpha1 +kind: ObjectStoreUser +metadata: + name: arrstack-media + namespace: arrstack +spec: + displayName: "arrstack media assets owner" + uid: arrstack-media + maxBuckets: 5 + secretName: arrstack-media-s3 + retainOnDelete: true +--- +apiVersion: ceph.unkin.net/v1alpha1 +kind: Bucket +metadata: + name: arrstack-media + namespace: arrstack +spec: + placementTarget: ec + bucketName: arrstack-media + ownerRef: arrstack-media + versioning: false + tags: + app: arrstack + purpose: media-assets + retainOnDelete: true diff --git a/apps/base/arrstack/radarr/deployment.yaml b/apps/base/arrstack/radarr/deployment.yaml index f52555f..a760b86 100644 --- a/apps/base/arrstack/radarr/deployment.yaml +++ b/apps/base/arrstack/radarr/deployment.yaml @@ -102,6 +102,33 @@ spec: secretKeyRef: name: radarr-apikey key: apitoken + # MediaCover object store (shared Ceph RGW bucket). Serves posters/fanart + # from S3 so any replica can render them instead of the leader-local + # emptyDir /config. Consumed by the -unkin3+ image; older images ignore + # these unknown config keys. Creds Secret is minted by cephrgw-operator. + - name: Radarr__MediaCover__S3__Endpoint + valueFrom: + secretKeyRef: + name: arrstack-media-s3 + key: S3_ENDPOINT + - name: Radarr__MediaCover__S3__AccessKey + valueFrom: + secretKeyRef: + name: arrstack-media-s3 + key: AWS_ACCESS_KEY_ID + - name: Radarr__MediaCover__S3__SecretKey + valueFrom: + secretKeyRef: + name: arrstack-media-s3 + key: AWS_SECRET_ACCESS_KEY + - name: Radarr__MediaCover__S3__Bucket + value: arrstack-media + - name: Radarr__MediaCover__S3__Prefix + value: radarr + - name: Radarr__MediaCover__S3__ForcePathStyle + value: "true" + - name: Radarr__MediaCover__S3__CaCertPath + value: /etc/ssl/vault-ca/ca.crt livenessProbe: httpGet: path: /radarr/ping @@ -130,9 +157,19 @@ spec: mountPath: /config - name: media-movies mountPath: /media/movies + - name: vault-ca + mountPath: /etc/ssl/vault-ca + readOnly: true volumes: - name: config emptyDir: {} - name: media-movies persistentVolumeClaim: claimName: media-movies + # 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 -- 2.47.3