Files
home-network-k3s-impl/catalog/sonarr.yaml
T
jakman85andClaude Opus 4.8 0f12950831 Onboard arr apps (Sonarr + Radarr) via ServiceDefinition renderer
Add catalog/sonarr.yaml and catalog/radarr.yaml ServiceDefinitions and their
rendered apps/*.yaml manifests, wired into apps/kustomization.yaml.

- exposure: internal, egress: vpn (R-NET-05/06 VPN + kill-switch, ADR-0015)
- auth: forward-auth, groups: media-users (R-IDP-02/06)
- dependencies -> qbittorrent:8080, jackett:9117 as explicit east-west
  CiliumNetworkPolicy egress allows on top of default-deny (R-NET-01/02)
- config on longhorn (R-STATE-02); bulk media/downloads volume DEFERRED
  pending OQ-2 (bulk StorageClass is a non-provisioning stub)
- observability up-SLI alert (R-OBS-01), daily-offcluster backup (R-STATE-03)

Rendered with catalog/render.py --no-image-automation. Offline gates green:
schema validate, kubectl kustomize apps, render.py --selftest, make -C ci gate.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-25 08:32:39 -05:00

49 lines
2.8 KiB
YAML

# 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)