feat(k8s/media): add Seerr media request manager

This commit is contained in:
2026-03-19 23:51:33 +02:00
parent 27a82f7832
commit a705573925
9 changed files with 320 additions and 39 deletions

View File

@@ -24,6 +24,7 @@ spec:
- qbittorrent
- sonarr
- radarr
- seerr
policyTypes:
- Ingress
ingress:
@@ -95,7 +96,7 @@ spec:
matchLabels:
app: radarr
---
# Allow prowlarr to reach sonarr, radarr, and qbittorrent
# Allow prowlarr and seerr to reach sonarr, radarr, and qbittorrent
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
@@ -117,6 +118,9 @@ spec:
- podSelector:
matchLabels:
app: prowlarr
- podSelector:
matchLabels:
app: seerr
---
# Allow qbittorrent to receive connections from sonarr, radarr, and external BT traffic
apiVersion: networking.k8s.io/v1
@@ -143,3 +147,42 @@ spec:
protocol: TCP
- port: 23312
protocol: UDP
---
# Allow jellyfin to reach seerr (cross-namespace)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-jellyfin-to-seerr
namespace: media
spec:
podSelector:
matchLabels:
app: seerr
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: jellyfin
podSelector:
matchLabels:
app: jellyfin
---
# seerr-db: only reachable from seerr
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: seerr-db
namespace: media
spec:
podSelector:
matchLabels:
app: seerr-db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: seerr

View File

@@ -95,3 +95,16 @@ spec:
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: seerr-config
namespace: media
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs-synology-ssd
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,88 @@
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: seerr
namespace: flux-system
spec:
chart:
spec:
chart: seerr-chart
reconcileStrategy: ChartVersion
sourceRef:
kind: HelmRepository
name: seerr
namespace: flux-system
version: 3.3.0
interval: 1m0s
targetNamespace: media
values:
image:
tag: v3.1.0
podLabels:
app: seerr
extraEnv:
- name: DB_TYPE
value: postgres
- name: DB_HOST
value: seerr-db
- name: DB_PORT
value: "5432"
- name: DB_USER
valueFrom:
secretKeyRef:
name: seerr-credentials
key: SEERR_DB_USER
- name: DB_PASS
valueFrom:
secretKeyRef:
name: seerr-credentials
key: SEERR_DB_PASSWORD
- name: DB_NAME
valueFrom:
secretKeyRef:
name: seerr-credentials
key: SEERR_DB_NAME
- name: TZ
value: Europe/Kyiv
probes:
startupProbe:
tcpSocket:
port: http
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30
livenessProbe:
httpGet:
port: http
path: /api/v1/status
periodSeconds: 30
failureThreshold: 5
readinessProbe:
httpGet:
port: http
path: /api/v1/status
periodSeconds: 10
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 512Mi
config:
persistence:
existingClaim: seerr-config
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt
traefik.ingress.kubernetes.io/router.middlewares: authelia-chain-authelia-authelia-auth@kubernetescrd
hosts:
- host: ${SEERR_HOST}
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- ${SEERR_HOST}
secretName: seerr-tls

View File

@@ -2,14 +2,28 @@
"kubernetes": {
"fileMatch": ["kubernetes/app/media/.+\\.yaml$"]
},
"customManagers": [
{
"customType": "regex",
"fileMatch": ["kubernetes/app/media/release-seerr\\.yaml$"],
"matchStrings": ["tag:\\s*(?<currentValue>v[^\\s]+)"],
"depNameTemplate": "seerr-team/seerr",
"datasourceTemplate": "github-releases"
}
],
"packageRules": [
{
"matchFileNames": ["kubernetes/app/media/**"],
"semanticCommitScope": "k8s/media"
},
{
"matchFileNames": ["kubernetes/app/media/**"],
"matchPackageNames": [
"lscr.io/linuxserver/sonarr",
"lscr.io/linuxserver/radarr",
"lscr.io/linuxserver/prowlarr",
"lscr.io/linuxserver/qbittorrent"
"lscr.io/linuxserver/qbittorrent",
"seerr-team/seerr"
],
"matchUpdateTypes": ["patch", "minor"],
"automerge": true
@@ -20,7 +34,8 @@
"lscr.io/linuxserver/sonarr",
"lscr.io/linuxserver/radarr",
"lscr.io/linuxserver/prowlarr",
"lscr.io/linuxserver/qbittorrent"
"lscr.io/linuxserver/qbittorrent",
"seerr-team/seerr"
],
"matchUpdateTypes": ["major"],
"automerge": false

View File

@@ -0,0 +1,10 @@
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: seerr
namespace: flux-system
spec:
interval: 1m0s
type: oci
url: oci://ghcr.io/seerr-team/seerr

View File

@@ -0,0 +1,24 @@
apiVersion: v1
kind: Secret
metadata:
name: seerr-credentials
namespace: media
stringData:
SEERR_DB_USER: ENC[AES256_GCM,data:wZ6luT0=,iv:VraZZ4R5ovGiJ8MHB1rvQYGX6xQpuoHNjmMO/JrmBDw=,tag:Hm812MdDtIneMJvLYN8PdA==,type:str]
SEERR_DB_PASSWORD: ENC[AES256_GCM,data:X4RCN3xDaHvoHz2A9wjWK3I8lLeVGIhb9/my3HJthqvO9f8cJ0U3uNUvX9a4itlhVcNVwkQFrC5xWJUABQhjntRpvLoOnfyR6KhnkbjcFWh6d6oNA+Tit+XCdvKyZlq2vNGjSYB+TBET0Of5dToiYYY+BoHqqWFGQPWhehYHwEg=,iv:3C0o2ZVpy2xSVFxa7aHNSQA9RZXM/rpVTXo+DOm/IF0=,tag:l1j1mVd15q/I+DSdrfjdcQ==,type:str]
SEERR_DB_NAME: ENC[AES256_GCM,data:dpi/Bno=,iv:W2q/1w3RlfU4xi4x8OMU1VDBiHxLaY+69aKTPltl9bE=,tag:4DLGDY8gJynzyyT336TDSg==,type:str]
sops:
age:
- recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4N0Z4dy9EQ3VyN0xxNzVj
SDVsZC9sTUdKQWdPYjBYSmNvWVlORXJ4cVFrClFBSTkzWE9sZU1TeW02bmJiT1d6
bVRydUxHbW83SHF0U0NEOVNCU296VUEKLS0tIDhxQ3IyekNva1VsWGhHakp2d1Ux
bzBCbm5hRUZ5bnh4eGhhVHB3MStkSXMKJwYKLl7o6rX+zf8X1MJwHjdusE942su4
QLduOA3pdm11nV2D/ssbx2OIi4inLdRvoR2kmx1WE5e2j4JdlcOokw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-03-19T21:50:13Z"
mac: ENC[AES256_GCM,data:R3w8Vwrt9gMEvBvBxsBOtZ/4WRRtn82VYKrJY9s1bgq9ePrptp3IKTyOBj1U4k1qdb8zjCtOatGQmTPhY2R+QQMXfrNUiyM/PFPOx5NRkONAWlxzMZbr79Dz1Og2V0pnelTSL7O9KGpcNZi7pL6tjACaYhI7cIt0jRABLoY8+fA=,iv:EnKlJ+TbDwDQzjE1Vjcl7gW062bh9tpyShj7onoKypQ=,tag:bHKmBCDwkm3cP08SwFysqg==,type:str]
encrypted_regex: ^(data|stringData|email)$
version: 3.12.1

View File

@@ -122,3 +122,20 @@ spec:
protocol: TCP
selector:
app: radarr-db
---
apiVersion: v1
kind: Service
metadata:
name: seerr-db
namespace: media
labels:
app: seerr-db
spec:
type: ClusterIP
ports:
- name: 5432-5432
port: 5432
targetPort: 5432
protocol: TCP
selector:
app: seerr-db

View File

@@ -0,0 +1,70 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: seerr-db
namespace: media
labels:
app: seerr-db
spec:
replicas: 1
serviceName: seerr-db
selector:
matchLabels:
app: seerr-db
template:
metadata:
labels:
app: seerr-db
spec:
securityContext:
runAsUser: 999
runAsGroup: 999
fsGroup: 999
containers:
- name: postgres
image: postgres:14.21
env:
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: seerr-credentials
key: SEERR_DB_NAME
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: seerr-credentials
key: SEERR_DB_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: seerr-credentials
key: SEERR_DB_PASSWORD
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
ports:
- containerPort: 5432
name: postgres
protocol: TCP
livenessProbe:
tcpSocket:
port: 5432
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 5
readinessProbe:
tcpSocket:
port: 5432
initialDelaySeconds: 5
periodSeconds: 10
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: nfs-synology-ssd
resources:
requests:
storage: 5Gi