Merge feature/onboard-arr: Sonarr + Radarr (VPN + arr->downloader allows)
This commit is contained in:
5 files changed
+570
No files matched your search
@@ -8,6 +8,8 @@ kind: Kustomization
|
|||||||
resources:
|
resources:
|
||||||
- pihole.yaml
|
- pihole.yaml
|
||||||
- gitea.yaml
|
- gitea.yaml
|
||||||
|
- sonarr.yaml
|
||||||
|
- radarr.yaml
|
||||||
- plex.yaml
|
- plex.yaml
|
||||||
- qbittorrent.yaml
|
- qbittorrent.yaml
|
||||||
- jackett.yaml
|
- jackett.yaml
|
||||||
@@ -0,0 +1,236 @@
|
|||||||
|
---
|
||||||
|
# Namespace (trust zone; default-deny + policies apply)
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: radarr
|
||||||
|
labels:
|
||||||
|
homelab.keithjackson.dev/app-namespace: 'true'
|
||||||
|
gateway-access: shared
|
||||||
|
annotations:
|
||||||
|
homelab.keithjackson.dev/backup-policy: daily-offcluster
|
||||||
|
---
|
||||||
|
# Default-deny baseline (R-NET-01): deny all, allow only DNS
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default-deny
|
||||||
|
namespace: radarr
|
||||||
|
labels:
|
||||||
|
homelab.keithjackson.dev/baseline: default-deny
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress: []
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
|
---
|
||||||
|
# PVC radarr-config (R-STATE)
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: radarr-config
|
||||||
|
namespace: radarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
storageClassName: longhorn
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
---
|
||||||
|
# Deployment (R-PLAT-02)
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: radarr
|
||||||
|
namespace: radarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
homelab.keithjackson.dev/egress-class: vpn
|
||||||
|
homelab.keithjackson.dev/auth-mode: forward-auth
|
||||||
|
annotations:
|
||||||
|
homelab.keithjackson.dev/auth-mode: forward-auth
|
||||||
|
homelab.keithjackson.dev/auth-groups: media-users
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: radarr
|
||||||
|
image: lscr.io/linuxserver/radarr:5.21.1
|
||||||
|
ports:
|
||||||
|
- containerPort: 7878
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /data/config
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: radarr-config
|
||||||
|
---
|
||||||
|
# Service
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: radarr
|
||||||
|
namespace: radarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
ports:
|
||||||
|
- name: port-7878
|
||||||
|
port: 7878
|
||||||
|
targetPort: 7878
|
||||||
|
---
|
||||||
|
# CiliumNetworkPolicy egress allow (R-NET-02): radarr-allow-qbittorrent-8080
|
||||||
|
apiVersion: cilium.io/v2
|
||||||
|
kind: CiliumNetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: radarr-allow-qbittorrent-8080
|
||||||
|
namespace: radarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
spec:
|
||||||
|
endpointSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
egress:
|
||||||
|
- toEndpoints:
|
||||||
|
- matchLabels:
|
||||||
|
app.kubernetes.io/name: qbittorrent
|
||||||
|
toPorts:
|
||||||
|
- ports:
|
||||||
|
- port: '8080'
|
||||||
|
protocol: TCP
|
||||||
|
---
|
||||||
|
# CiliumNetworkPolicy egress allow (R-NET-02): radarr-allow-jackett-9117
|
||||||
|
apiVersion: cilium.io/v2
|
||||||
|
kind: CiliumNetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: radarr-allow-jackett-9117
|
||||||
|
namespace: radarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
spec:
|
||||||
|
endpointSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
egress:
|
||||||
|
- toEndpoints:
|
||||||
|
- matchLabels:
|
||||||
|
app.kubernetes.io/name: jackett
|
||||||
|
toPorts:
|
||||||
|
- ports:
|
||||||
|
- port: '9117'
|
||||||
|
protocol: TCP
|
||||||
|
---
|
||||||
|
# CiliumNetworkPolicy gateway-ingress allow (R-NET-01/02): radarr-allow-gateway-ingress
|
||||||
|
apiVersion: cilium.io/v2
|
||||||
|
kind: CiliumNetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: radarr-allow-gateway-ingress
|
||||||
|
namespace: radarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
spec:
|
||||||
|
endpointSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
ingress:
|
||||||
|
- fromEntities:
|
||||||
|
- ingress
|
||||||
|
toPorts:
|
||||||
|
- ports:
|
||||||
|
- port: '7878'
|
||||||
|
protocol: TCP
|
||||||
|
---
|
||||||
|
# HTTPRoute radarr-7878 (R-TLS/R-DNS)
|
||||||
|
apiVersion: gateway.networking.k8s.io/v1
|
||||||
|
kind: HTTPRoute
|
||||||
|
metadata:
|
||||||
|
name: radarr-7878
|
||||||
|
namespace: radarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
annotations:
|
||||||
|
homelab.keithjackson.dev/auth-mode: forward-auth
|
||||||
|
homelab.keithjackson.dev/auth-groups: media-users
|
||||||
|
spec:
|
||||||
|
parentRefs:
|
||||||
|
- name: shared
|
||||||
|
namespace: gateway
|
||||||
|
sectionName: https
|
||||||
|
hostnames:
|
||||||
|
- radarr.home.keithjackson.dev
|
||||||
|
rules:
|
||||||
|
- matches:
|
||||||
|
- path:
|
||||||
|
type: PathPrefix
|
||||||
|
value: /
|
||||||
|
backendRefs:
|
||||||
|
- name: radarr
|
||||||
|
port: 7878
|
||||||
|
---
|
||||||
|
# ServiceMonitor (R-OBS-01)
|
||||||
|
apiVersion: monitoring.coreos.com/v1
|
||||||
|
kind: ServiceMonitor
|
||||||
|
metadata:
|
||||||
|
name: radarr
|
||||||
|
namespace: radarr
|
||||||
|
labels:
|
||||||
|
release: kube-prometheus-stack
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
namespaceSelector:
|
||||||
|
matchNames:
|
||||||
|
- radarr
|
||||||
|
endpoints:
|
||||||
|
- port: metrics
|
||||||
|
interval: 30s
|
||||||
|
---
|
||||||
|
# PrometheusRule SLI alerts (R-OBS-01)
|
||||||
|
apiVersion: monitoring.coreos.com/v1
|
||||||
|
kind: PrometheusRule
|
||||||
|
metadata:
|
||||||
|
name: radarr-slis
|
||||||
|
namespace: radarr
|
||||||
|
labels:
|
||||||
|
release: kube-prometheus-stack
|
||||||
|
app.kubernetes.io/name: radarr
|
||||||
|
spec:
|
||||||
|
groups:
|
||||||
|
- name: radarr.slis
|
||||||
|
rules:
|
||||||
|
- alert: radarr-down
|
||||||
|
expr: up{job="radarr"} == 0
|
||||||
|
for: 5m
|
||||||
|
labels:
|
||||||
|
severity: critical
|
||||||
|
service: radarr
|
||||||
|
annotations:
|
||||||
|
summary: radarr is down
|
||||||
|
description: 'radarr has been unreachable for 5m (SLI: up).'
|
||||||
@@ -0,0 +1,236 @@
|
|||||||
|
---
|
||||||
|
# Namespace (trust zone; default-deny + policies apply)
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: sonarr
|
||||||
|
labels:
|
||||||
|
homelab.keithjackson.dev/app-namespace: 'true'
|
||||||
|
gateway-access: shared
|
||||||
|
annotations:
|
||||||
|
homelab.keithjackson.dev/backup-policy: daily-offcluster
|
||||||
|
---
|
||||||
|
# Default-deny baseline (R-NET-01): deny all, allow only DNS
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default-deny
|
||||||
|
namespace: sonarr
|
||||||
|
labels:
|
||||||
|
homelab.keithjackson.dev/baseline: default-deny
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress: []
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
|
---
|
||||||
|
# PVC sonarr-config (R-STATE)
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: sonarr-config
|
||||||
|
namespace: sonarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
storageClassName: longhorn
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
---
|
||||||
|
# Deployment (R-PLAT-02)
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: sonarr
|
||||||
|
namespace: sonarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
homelab.keithjackson.dev/egress-class: vpn
|
||||||
|
homelab.keithjackson.dev/auth-mode: forward-auth
|
||||||
|
annotations:
|
||||||
|
homelab.keithjackson.dev/auth-mode: forward-auth
|
||||||
|
homelab.keithjackson.dev/auth-groups: media-users
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: sonarr
|
||||||
|
image: lscr.io/linuxserver/sonarr:4.0.15
|
||||||
|
ports:
|
||||||
|
- containerPort: 8989
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /data/config
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: sonarr-config
|
||||||
|
---
|
||||||
|
# Service
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: sonarr
|
||||||
|
namespace: sonarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
ports:
|
||||||
|
- name: port-8989
|
||||||
|
port: 8989
|
||||||
|
targetPort: 8989
|
||||||
|
---
|
||||||
|
# CiliumNetworkPolicy egress allow (R-NET-02): sonarr-allow-qbittorrent-8080
|
||||||
|
apiVersion: cilium.io/v2
|
||||||
|
kind: CiliumNetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: sonarr-allow-qbittorrent-8080
|
||||||
|
namespace: sonarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
spec:
|
||||||
|
endpointSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
egress:
|
||||||
|
- toEndpoints:
|
||||||
|
- matchLabels:
|
||||||
|
app.kubernetes.io/name: qbittorrent
|
||||||
|
toPorts:
|
||||||
|
- ports:
|
||||||
|
- port: '8080'
|
||||||
|
protocol: TCP
|
||||||
|
---
|
||||||
|
# CiliumNetworkPolicy egress allow (R-NET-02): sonarr-allow-jackett-9117
|
||||||
|
apiVersion: cilium.io/v2
|
||||||
|
kind: CiliumNetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: sonarr-allow-jackett-9117
|
||||||
|
namespace: sonarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
spec:
|
||||||
|
endpointSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
egress:
|
||||||
|
- toEndpoints:
|
||||||
|
- matchLabels:
|
||||||
|
app.kubernetes.io/name: jackett
|
||||||
|
toPorts:
|
||||||
|
- ports:
|
||||||
|
- port: '9117'
|
||||||
|
protocol: TCP
|
||||||
|
---
|
||||||
|
# CiliumNetworkPolicy gateway-ingress allow (R-NET-01/02): sonarr-allow-gateway-ingress
|
||||||
|
apiVersion: cilium.io/v2
|
||||||
|
kind: CiliumNetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: sonarr-allow-gateway-ingress
|
||||||
|
namespace: sonarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
spec:
|
||||||
|
endpointSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
ingress:
|
||||||
|
- fromEntities:
|
||||||
|
- ingress
|
||||||
|
toPorts:
|
||||||
|
- ports:
|
||||||
|
- port: '8989'
|
||||||
|
protocol: TCP
|
||||||
|
---
|
||||||
|
# HTTPRoute sonarr-8989 (R-TLS/R-DNS)
|
||||||
|
apiVersion: gateway.networking.k8s.io/v1
|
||||||
|
kind: HTTPRoute
|
||||||
|
metadata:
|
||||||
|
name: sonarr-8989
|
||||||
|
namespace: sonarr
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
annotations:
|
||||||
|
homelab.keithjackson.dev/auth-mode: forward-auth
|
||||||
|
homelab.keithjackson.dev/auth-groups: media-users
|
||||||
|
spec:
|
||||||
|
parentRefs:
|
||||||
|
- name: shared
|
||||||
|
namespace: gateway
|
||||||
|
sectionName: https
|
||||||
|
hostnames:
|
||||||
|
- sonarr.home.keithjackson.dev
|
||||||
|
rules:
|
||||||
|
- matches:
|
||||||
|
- path:
|
||||||
|
type: PathPrefix
|
||||||
|
value: /
|
||||||
|
backendRefs:
|
||||||
|
- name: sonarr
|
||||||
|
port: 8989
|
||||||
|
---
|
||||||
|
# ServiceMonitor (R-OBS-01)
|
||||||
|
apiVersion: monitoring.coreos.com/v1
|
||||||
|
kind: ServiceMonitor
|
||||||
|
metadata:
|
||||||
|
name: sonarr
|
||||||
|
namespace: sonarr
|
||||||
|
labels:
|
||||||
|
release: kube-prometheus-stack
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
namespaceSelector:
|
||||||
|
matchNames:
|
||||||
|
- sonarr
|
||||||
|
endpoints:
|
||||||
|
- port: metrics
|
||||||
|
interval: 30s
|
||||||
|
---
|
||||||
|
# PrometheusRule SLI alerts (R-OBS-01)
|
||||||
|
apiVersion: monitoring.coreos.com/v1
|
||||||
|
kind: PrometheusRule
|
||||||
|
metadata:
|
||||||
|
name: sonarr-slis
|
||||||
|
namespace: sonarr
|
||||||
|
labels:
|
||||||
|
release: kube-prometheus-stack
|
||||||
|
app.kubernetes.io/name: sonarr
|
||||||
|
spec:
|
||||||
|
groups:
|
||||||
|
- name: sonarr.slis
|
||||||
|
rules:
|
||||||
|
- alert: sonarr-down
|
||||||
|
expr: up{job="sonarr"} == 0
|
||||||
|
for: 5m
|
||||||
|
labels:
|
||||||
|
severity: critical
|
||||||
|
service: sonarr
|
||||||
|
annotations:
|
||||||
|
summary: sonarr is down
|
||||||
|
description: 'sonarr has been unreachable for 5m (SLI: up).'
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# ServiceDefinition: radarr
|
||||||
|
# Source of truth: spec docs/13-service-catalog.md row 3; docs/15-identity-and-access.md; docs/03.
|
||||||
|
# internal | egress VPN (+ kill-switch) | config on Longhorn | auth forward-auth | arr→downloaders.
|
||||||
|
# Radarr (movies) scrapes indexers and hands releases to the download client; both of those hops leave
|
||||||
|
# the cluster over the shared PIA/WireGuard egress gateway (egress: vpn, ADR-0015; R-NET-05/06), and
|
||||||
|
# the intra-cluster hops to qbittorrent/jackett are EXPLICIT east-west allows on top of default-deny
|
||||||
|
# (R-NET-01/02). Validates against schemas/servicedefinition.schema.json.
|
||||||
|
name: radarr
|
||||||
|
kind: container
|
||||||
|
source:
|
||||||
|
image: lscr.io/linuxserver/radarr:5.21.1 # pinned stable v5 tag (R-UPD-01); update.range governs advancement
|
||||||
|
exposure: internal # LAN-only web UI at radarr.home.keithjackson.dev (docs/13 row 3; R-DNS/R-NET)
|
||||||
|
egress: vpn # indexer scrape + downloader handoff steered via the shared VPN egress gateway,
|
||||||
|
# kill-switch enforced OUTSIDE the workload (docs/03; ADR-0015; R-NET-05/06)
|
||||||
|
storage:
|
||||||
|
- name: config
|
||||||
|
size: 5Gi
|
||||||
|
class: longhorn # app DB / config on the 3-replica tier; DR-critical (docs/04; R-STATE-02)
|
||||||
|
# NOTE (bulk-media PREREQUISITE): docs/13 row 3 places the media library / downloads volume on the
|
||||||
|
# `bulk` tier (R-STATE-04). The `bulk` StorageClass exists (platform/longhorn/storageclasses.yaml)
|
||||||
|
# but is a NON-provisioning STUB pending OQ-2 (NFS/SMB backing = REPLACE-ME). Adding a `class: bulk`
|
||||||
|
# volume now would leave the PVC (and therefore the pod) Pending. The media/downloads volume is
|
||||||
|
# therefore DEFERRED until OQ-2 is resolved; config-only on longhorn keeps Radarr deployable today.
|
||||||
|
dependencies:
|
||||||
|
- to: qbittorrent # arr → download client (docs/13 dependency graph; R-NET-02 explicit allow)
|
||||||
|
port: 8080
|
||||||
|
protocol: tcp
|
||||||
|
- to: jackett # arr → indexer proxy (docs/13 dependency graph; R-NET-02 explicit allow)
|
||||||
|
port: 9117
|
||||||
|
protocol: tcp
|
||||||
|
ingressRoutes:
|
||||||
|
- host: radarr.home.keithjackson.dev
|
||||||
|
port: 7878 # Radarr web/API; TLS terminates at the shared Gateway (docs/08, docs/09)
|
||||||
|
auth:
|
||||||
|
mode: forward-auth # bare UI, no usable OIDC: oauth2-proxy → Keycloak at the Gateway (docs/15; R-IDP-02)
|
||||||
|
groups:
|
||||||
|
- media-users # authenticated AND in the media group (R-IDP-06)
|
||||||
|
update:
|
||||||
|
channel: stable # R-UPD-01
|
||||||
|
range: ">=5.0.0 <6.0.0" # stay on the Radarr v5 stable line
|
||||||
|
cadence: "0 4 * * *"
|
||||||
|
autoRollbackOnFailedHealth: true # R-UPD-03
|
||||||
|
observability:
|
||||||
|
metrics: true
|
||||||
|
slis:
|
||||||
|
- up # arr down => alert (docs/10; R-OBS-01)
|
||||||
|
backup:
|
||||||
|
policy: daily-offcluster # Radarr config/DB is irreplaceable, backed up off-cluster (docs/04; R-STATE-03)
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# ServiceDefinition: sonarr
|
||||||
|
# Source of truth: spec docs/13-service-catalog.md row 2; docs/15-identity-and-access.md; docs/03.
|
||||||
|
# internal | egress VPN (+ kill-switch) | config on Longhorn | auth forward-auth | arr→downloaders.
|
||||||
|
# Sonarr (TV) scrapes indexers and hands releases to the download client; both of those hops leave
|
||||||
|
# the cluster over the shared PIA/WireGuard egress gateway (egress: vpn, ADR-0015; R-NET-05/06), and
|
||||||
|
# the intra-cluster hops to qbittorrent/jackett are EXPLICIT east-west allows on top of default-deny
|
||||||
|
# (R-NET-01/02). Validates against schemas/servicedefinition.schema.json.
|
||||||
|
name: sonarr
|
||||||
|
kind: container
|
||||||
|
source:
|
||||||
|
image: lscr.io/linuxserver/sonarr:4.0.15 # pinned stable v4 tag (R-UPD-01); update.range governs advancement
|
||||||
|
exposure: internal # LAN-only web UI at sonarr.home.keithjackson.dev (docs/13 row 2; R-DNS/R-NET)
|
||||||
|
egress: vpn # indexer scrape + downloader handoff steered via the shared VPN egress gateway,
|
||||||
|
# kill-switch enforced OUTSIDE the workload (docs/03; ADR-0015; R-NET-05/06)
|
||||||
|
storage:
|
||||||
|
- name: config
|
||||||
|
size: 5Gi
|
||||||
|
class: longhorn # app DB / config on the 3-replica tier; DR-critical (docs/04; R-STATE-02)
|
||||||
|
# NOTE (bulk-media PREREQUISITE): docs/13 row 2 places the media library / downloads volume on the
|
||||||
|
# `bulk` tier (R-STATE-04). The `bulk` StorageClass exists (platform/longhorn/storageclasses.yaml)
|
||||||
|
# but is a NON-provisioning STUB pending OQ-2 (NFS/SMB backing = REPLACE-ME). Adding a `class: bulk`
|
||||||
|
# volume now would leave the PVC (and therefore the pod) Pending. The media/downloads volume is
|
||||||
|
# therefore DEFERRED until OQ-2 is resolved; config-only on longhorn keeps Sonarr deployable today.
|
||||||
|
dependencies:
|
||||||
|
- to: qbittorrent # arr → download client (docs/13 dependency graph; R-NET-02 explicit allow)
|
||||||
|
port: 8080
|
||||||
|
protocol: tcp
|
||||||
|
- to: jackett # arr → indexer proxy (docs/13 dependency graph; R-NET-02 explicit allow)
|
||||||
|
port: 9117
|
||||||
|
protocol: tcp
|
||||||
|
ingressRoutes:
|
||||||
|
- host: sonarr.home.keithjackson.dev
|
||||||
|
port: 8989 # Sonarr web/API; TLS terminates at the shared Gateway (docs/08, docs/09)
|
||||||
|
auth:
|
||||||
|
mode: forward-auth # bare UI, no usable OIDC: oauth2-proxy → Keycloak at the Gateway (docs/15; R-IDP-02)
|
||||||
|
groups:
|
||||||
|
- media-users # authenticated AND in the media group (R-IDP-06)
|
||||||
|
update:
|
||||||
|
channel: stable # R-UPD-01
|
||||||
|
range: ">=4.0.0 <5.0.0" # stay on the Sonarr v4 stable line
|
||||||
|
cadence: "0 4 * * *"
|
||||||
|
autoRollbackOnFailedHealth: true # R-UPD-03
|
||||||
|
observability:
|
||||||
|
metrics: true
|
||||||
|
slis:
|
||||||
|
- up # arr down => alert (docs/10; R-OBS-01)
|
||||||
|
backup:
|
||||||
|
policy: daily-offcluster # Sonarr config/DB is irreplaceable, backed up off-cluster (docs/04; R-STATE-03)
|
||||||
Reference in new issue
Block a user