Add media stack: Plex, Radarr, Sonarr, Prowlarr, qBittorrent, Bazarr, Overseerr
- Namespace: media (created via Terraform)
- Storage: hostPath PV at /media on Legion (movies, tv/shows, tv/anime, downloads)
- VPN: gluetun sidecar with ProtonVPN WireGuard (US-TX#253), all torrent traffic tunneled
- Radarr: movie automation with /media/movies root
- Sonarr: TV/anime automation with /media/tv/{shows,anime} roots
- Prowlarr: indexer aggregator (YTS, 1337x, Nyaa for anime)
- qBittorrent: torrent client, network namespaced behind gluetun VPN
- Bazarr: automatic subtitle downloads (connects to Radarr + Sonarr)
- Overseerr: family request portal at watch.nook.family
- Plex: media server at plex.nook.family
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: media
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://git.neuralplatform.ai/will/infrastructure.git
|
||||
targetRevision: main
|
||||
path: servers/legion/k8s/media
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: media
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
@@ -0,0 +1,77 @@
|
||||
# Bazarr — automatic subtitle downloader
|
||||
# Connects to Radarr + Sonarr, downloads subtitles from OpenSubtitles/Subscene/etc.
|
||||
# After deploy, configure at bazarr:6767:
|
||||
# 1. Settings > Radarr: URL=http://radarr:7878, API key from Radarr Settings > General
|
||||
# 2. Settings > Sonarr: URL=http://sonarr:8989, API key from Sonarr Settings > General
|
||||
# 3. Settings > Providers: add OpenSubtitles.com (free account) for best coverage
|
||||
# 4. Settings > Languages: add English (and any other desired languages)
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bazarr
|
||||
namespace: media
|
||||
labels:
|
||||
app: bazarr
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: bazarr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: bazarr
|
||||
spec:
|
||||
containers:
|
||||
- name: bazarr
|
||||
image: lscr.io/linuxserver/bazarr:latest
|
||||
env:
|
||||
- name: PUID
|
||||
value: "1000"
|
||||
- name: PGID
|
||||
value: "1000"
|
||||
- name: TZ
|
||||
value: "America/Chicago"
|
||||
ports:
|
||||
- containerPort: 6767
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: media
|
||||
mountPath: /media
|
||||
resources:
|
||||
requests:
|
||||
memory: 128Mi
|
||||
cpu: 50m
|
||||
limits:
|
||||
memory: 512Mi
|
||||
cpu: 200m
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 6767
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: bazarr-config
|
||||
- name: media
|
||||
persistentVolumeClaim:
|
||||
claimName: media-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: bazarr
|
||||
namespace: media
|
||||
spec:
|
||||
selector:
|
||||
app: bazarr
|
||||
ports:
|
||||
- name: http
|
||||
port: 6767
|
||||
targetPort: 6767
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,25 @@
|
||||
# media-secrets — ProtonVPN WireGuard key + Plex claim token
|
||||
# PLEX_CLAIM: run `vault kv patch secret/plex claim_token=<token>` right before first deploy
|
||||
# Get token from: https://www.plex.tv/claim (expires in 4 minutes)
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: media-secrets
|
||||
namespace: media
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: vault
|
||||
kind: ClusterSecretStore
|
||||
target:
|
||||
name: media-secrets
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: PROTONVPN_PRIVATE_KEY
|
||||
remoteRef:
|
||||
key: secret/data/protonvpn
|
||||
property: private_key
|
||||
- secretKey: PLEX_CLAIM
|
||||
remoteRef:
|
||||
key: secret/data/plex
|
||||
property: claim_token
|
||||
@@ -0,0 +1,115 @@
|
||||
# gluetun + qBittorrent — all torrent traffic routed through ProtonVPN WireGuard
|
||||
# gluetun runs as the VPN container; qBittorrent shares its network namespace (same pod)
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: qbittorrent
|
||||
namespace: media
|
||||
labels:
|
||||
app: qbittorrent
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: qbittorrent
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: qbittorrent
|
||||
spec:
|
||||
initContainers:
|
||||
# Ensure /dev/net/tun exists on the node
|
||||
- name: tun-setup
|
||||
image: busybox:latest
|
||||
command: ["sh", "-c", "mkdir -p /dev/net && [ -c /dev/net/tun ] || mknod /dev/net/tun c 10 200 && chmod 666 /dev/net/tun"]
|
||||
securityContext:
|
||||
privileged: true
|
||||
containers:
|
||||
# VPN container — must come first so network is up before qBittorrent starts
|
||||
- name: gluetun
|
||||
image: ghcr.io/qdm12/gluetun:latest
|
||||
securityContext:
|
||||
capabilities:
|
||||
add: ["NET_ADMIN"]
|
||||
env:
|
||||
- name: VPN_SERVICE_PROVIDER
|
||||
value: "custom"
|
||||
- name: VPN_TYPE
|
||||
value: "wireguard"
|
||||
- name: WIREGUARD_PRIVATE_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: media-secrets
|
||||
key: PROTONVPN_PRIVATE_KEY
|
||||
- name: WIREGUARD_PUBLIC_KEY
|
||||
value: "mngiSxBpH7GU24nnWdBEcnhDnCPn2jq5+ZP3zwPwISA="
|
||||
- name: WIREGUARD_ADDRESSES
|
||||
value: "10.2.0.2/32"
|
||||
- name: VPN_ENDPOINT_IP
|
||||
value: "95.173.217.29"
|
||||
- name: VPN_ENDPOINT_PORT
|
||||
value: "51820"
|
||||
# Allow cluster-internal traffic to bypass VPN (for Radarr/Sonarr → qBittorrent API)
|
||||
- name: FIREWALL_OUTBOUND_SUBNETS
|
||||
value: "10.42.0.0/16,10.43.0.0/16"
|
||||
- name: UPDATER_PERIOD
|
||||
value: "0"
|
||||
ports:
|
||||
- containerPort: 8888 # gluetun HTTP proxy (unused but required)
|
||||
resources:
|
||||
requests:
|
||||
memory: 64Mi
|
||||
cpu: 50m
|
||||
limits:
|
||||
memory: 128Mi
|
||||
cpu: 200m
|
||||
|
||||
# qBittorrent — shares gluetun's network namespace, all traffic through VPN
|
||||
- name: qbittorrent
|
||||
image: lscr.io/linuxserver/qbittorrent:latest
|
||||
env:
|
||||
- name: PUID
|
||||
value: "1000"
|
||||
- name: PGID
|
||||
value: "1000"
|
||||
- name: TZ
|
||||
value: "America/Chicago"
|
||||
- name: WEBUI_PORT
|
||||
value: "8080"
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: media
|
||||
mountPath: /media
|
||||
resources:
|
||||
requests:
|
||||
memory: 256Mi
|
||||
cpu: 100m
|
||||
limits:
|
||||
memory: 1Gi
|
||||
cpu: 500m
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: qbittorrent-config
|
||||
- name: media
|
||||
persistentVolumeClaim:
|
||||
claimName: media-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: qbittorrent
|
||||
namespace: media
|
||||
spec:
|
||||
selector:
|
||||
app: qbittorrent
|
||||
ports:
|
||||
- name: webui
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,58 @@
|
||||
# watch.nook.family → Overseerr (family request portal)
|
||||
# NOTE: After deploying, add this route in Cloudflare Zero Trust:
|
||||
# Zero Trust > Networks > Tunnels > neural-platform > Public Hostname
|
||||
# Hostname: watch.nook.family | Service: http://traefik.kube-system:80
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: overseerr
|
||||
namespace: media
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
tls:
|
||||
- hosts:
|
||||
- watch.nook.family
|
||||
secretName: overseerr-tls
|
||||
rules:
|
||||
- host: watch.nook.family
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: overseerr
|
||||
port:
|
||||
number: 5055
|
||||
---
|
||||
# plex.nook.family → Plex
|
||||
# NOTE: Also add in Cloudflare Zero Trust:
|
||||
# Hostname: plex.nook.family | Service: http://traefik.kube-system:80
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: plex
|
||||
namespace: media
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
tls:
|
||||
- hosts:
|
||||
- plex.nook.family
|
||||
secretName: plex-tls
|
||||
rules:
|
||||
- host: plex.nook.family
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: plex
|
||||
port:
|
||||
number: 32400
|
||||
@@ -0,0 +1,75 @@
|
||||
# Overseerr — family request portal (watch.nook.family)
|
||||
# Family members browse and request content here
|
||||
# After deploy, complete setup wizard at watch.nook.family:
|
||||
# 1. Sign in with Plex account
|
||||
# 2. Connect to Plex server
|
||||
# 3. Add Radarr (http://radarr:7878) and Sonarr (http://sonarr:8989)
|
||||
# 4. Create managed user accounts for each family member
|
||||
# 5. Set request permissions per user (kids require approval)
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: overseerr
|
||||
namespace: media
|
||||
labels:
|
||||
app: overseerr
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: overseerr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: overseerr
|
||||
spec:
|
||||
containers:
|
||||
- name: overseerr
|
||||
image: sctx/overseerr:latest
|
||||
env:
|
||||
- name: TZ
|
||||
value: "America/Chicago"
|
||||
ports:
|
||||
- containerPort: 5055
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /app/config
|
||||
resources:
|
||||
requests:
|
||||
memory: 256Mi
|
||||
cpu: 100m
|
||||
limits:
|
||||
memory: 1Gi
|
||||
cpu: 500m
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/status
|
||||
port: 5055
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/status
|
||||
port: 5055
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 10
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: overseerr-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: overseerr
|
||||
namespace: media
|
||||
spec:
|
||||
selector:
|
||||
app: overseerr
|
||||
ports:
|
||||
- name: http
|
||||
port: 5055
|
||||
targetPort: 5055
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,103 @@
|
||||
# Plex Media Server
|
||||
# BEFORE FIRST DEPLOY: add claim token to Vault
|
||||
# 1. Go to https://www.plex.tv/claim (token expires in 4 minutes)
|
||||
# 2. vault kv put secret/plex claim_token=<token>
|
||||
# 3. Then push and let Argo CD deploy
|
||||
# After first startup the token is stored in config and can be left as-is
|
||||
#
|
||||
# Post-deploy setup:
|
||||
# 1. Access via plex.nook.family or port-forward :32400
|
||||
# 2. Add libraries:
|
||||
# - Movies → /media/movies
|
||||
# - TV Shows → /media/tv/shows
|
||||
# - Anime (TV Shows) → /media/tv/anime
|
||||
# 3. Settings > Manage > Users & Sharing → create Plex Home managed users
|
||||
# 4. Set content rating limits per child profile (G/PG/PG-13)
|
||||
# 5. Enable PIN on adult profiles
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: plex
|
||||
namespace: media
|
||||
labels:
|
||||
app: plex
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: plex
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: plex
|
||||
spec:
|
||||
containers:
|
||||
- name: plex
|
||||
image: lscr.io/linuxserver/plex:latest
|
||||
env:
|
||||
- name: PUID
|
||||
value: "1000"
|
||||
- name: PGID
|
||||
value: "1000"
|
||||
- name: TZ
|
||||
value: "America/Chicago"
|
||||
- name: VERSION
|
||||
value: "docker"
|
||||
- name: PLEX_CLAIM
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: media-secrets
|
||||
key: PLEX_CLAIM
|
||||
optional: true # safe after first boot
|
||||
- name: ADVERTISE_IP
|
||||
value: "https://plex.nook.family:443"
|
||||
ports:
|
||||
- containerPort: 32400
|
||||
name: plex
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: media
|
||||
mountPath: /media
|
||||
resources:
|
||||
requests:
|
||||
memory: 1Gi
|
||||
cpu: 500m
|
||||
limits:
|
||||
memory: 4Gi
|
||||
cpu: 2000m
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /identity
|
||||
port: 32400
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /identity
|
||||
port: 32400
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: plex-config
|
||||
- name: media
|
||||
persistentVolumeClaim:
|
||||
claimName: media-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: plex
|
||||
namespace: media
|
||||
spec:
|
||||
selector:
|
||||
app: plex
|
||||
ports:
|
||||
- name: plex
|
||||
port: 32400
|
||||
targetPort: 32400
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,74 @@
|
||||
# Prowlarr — indexer aggregator (connects to torrent trackers, feeds Radarr + Sonarr)
|
||||
# After deploy, add indexers at prowlarr:9696:
|
||||
# Recommended public indexers for movies/TV/anime:
|
||||
# - YTS (movies — excellent quality, very reliable)
|
||||
# - 1337x (general)
|
||||
# - TorrentGalaxy (general)
|
||||
# - Nyaa.si (anime — essential for anime/manga)
|
||||
# - AnimeTosho (anime with good subtitle/dub tagging)
|
||||
# Then sync to Radarr + Sonarr via Settings > Apps
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: prowlarr
|
||||
namespace: media
|
||||
labels:
|
||||
app: prowlarr
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: prowlarr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: prowlarr
|
||||
spec:
|
||||
containers:
|
||||
- name: prowlarr
|
||||
image: lscr.io/linuxserver/prowlarr:latest
|
||||
env:
|
||||
- name: PUID
|
||||
value: "1000"
|
||||
- name: PGID
|
||||
value: "1000"
|
||||
- name: TZ
|
||||
value: "America/Chicago"
|
||||
ports:
|
||||
- containerPort: 9696
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
resources:
|
||||
requests:
|
||||
memory: 128Mi
|
||||
cpu: 50m
|
||||
limits:
|
||||
memory: 512Mi
|
||||
cpu: 300m
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /ping
|
||||
port: 9696
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: prowlarr-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: prowlarr
|
||||
namespace: media
|
||||
spec:
|
||||
selector:
|
||||
app: prowlarr
|
||||
ports:
|
||||
- name: http
|
||||
port: 9696
|
||||
targetPort: 9696
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,124 @@
|
||||
# Shared media PV — hostPath /media on Legion (single-node cluster)
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: media-data
|
||||
spec:
|
||||
capacity:
|
||||
storage: 500Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
storageClassName: ""
|
||||
hostPath:
|
||||
path: /media
|
||||
type: Directory
|
||||
claimRef:
|
||||
namespace: media
|
||||
name: media-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: media-data
|
||||
namespace: media
|
||||
spec:
|
||||
storageClassName: ""
|
||||
volumeName: media-data
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 500Gi
|
||||
---
|
||||
# Per-service config PVCs (small, local-path provisioner)
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: plex-config
|
||||
namespace: media
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: radarr-config
|
||||
namespace: media
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 2Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: sonarr-config
|
||||
namespace: media
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 2Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: prowlarr-config
|
||||
namespace: media
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: qbittorrent-config
|
||||
namespace: media
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: bazarr-config
|
||||
namespace: media
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: overseerr-config
|
||||
namespace: media
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
@@ -0,0 +1,80 @@
|
||||
# Radarr — movie automation (monitors new releases, grabs torrents via Prowlarr/qBittorrent)
|
||||
# After deploy, configure at http://radarr.media.svc:7878 or via kubectl port-forward
|
||||
# Root folder: /media/movies | Download client: qbittorrent:8080
|
||||
# Quality profile: set MPAA filter to allow G/PG/PG-13/R/NR (unrated for documentaries)
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: radarr
|
||||
namespace: media
|
||||
labels:
|
||||
app: radarr
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: radarr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: radarr
|
||||
spec:
|
||||
containers:
|
||||
- name: radarr
|
||||
image: lscr.io/linuxserver/radarr:latest
|
||||
env:
|
||||
- name: PUID
|
||||
value: "1000"
|
||||
- name: PGID
|
||||
value: "1000"
|
||||
- name: TZ
|
||||
value: "America/Chicago"
|
||||
ports:
|
||||
- containerPort: 7878
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: media
|
||||
mountPath: /media
|
||||
resources:
|
||||
requests:
|
||||
memory: 256Mi
|
||||
cpu: 100m
|
||||
limits:
|
||||
memory: 1Gi
|
||||
cpu: 500m
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /ping
|
||||
port: 7878
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ping
|
||||
port: 7878
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 10
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: radarr-config
|
||||
- name: media
|
||||
persistentVolumeClaim:
|
||||
claimName: media-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: radarr
|
||||
namespace: media
|
||||
spec:
|
||||
selector:
|
||||
app: radarr
|
||||
ports:
|
||||
- name: http
|
||||
port: 7878
|
||||
targetPort: 7878
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,81 @@
|
||||
# Sonarr — TV show & anime automation
|
||||
# After deploy, configure at sonarr:8989
|
||||
# Root folders: /media/tv/shows and /media/tv/anime
|
||||
# For anime: add custom format preferring "Dual Audio" / "English Dub" releases
|
||||
# Download client: qbittorrent:8080
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sonarr
|
||||
namespace: media
|
||||
labels:
|
||||
app: sonarr
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: sonarr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: sonarr
|
||||
spec:
|
||||
containers:
|
||||
- name: sonarr
|
||||
image: lscr.io/linuxserver/sonarr:latest
|
||||
env:
|
||||
- name: PUID
|
||||
value: "1000"
|
||||
- name: PGID
|
||||
value: "1000"
|
||||
- name: TZ
|
||||
value: "America/Chicago"
|
||||
ports:
|
||||
- containerPort: 8989
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: media
|
||||
mountPath: /media
|
||||
resources:
|
||||
requests:
|
||||
memory: 256Mi
|
||||
cpu: 100m
|
||||
limits:
|
||||
memory: 1Gi
|
||||
cpu: 500m
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /ping
|
||||
port: 8989
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ping
|
||||
port: 8989
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 10
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: sonarr-config
|
||||
- name: media
|
||||
persistentVolumeClaim:
|
||||
claimName: media-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: sonarr
|
||||
namespace: media
|
||||
spec:
|
||||
selector:
|
||||
app: sonarr
|
||||
ports:
|
||||
- name: http
|
||||
port: 8989
|
||||
targetPort: 8989
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,13 @@
|
||||
# Media stack — Plex, Radarr, Sonarr, Prowlarr, qBittorrent, Bazarr, Overseerr
|
||||
# Namespace only — all resources managed by Argo CD
|
||||
# See: apps/media.yaml, k8s/media/
|
||||
|
||||
resource "kubernetes_namespace" "media" {
|
||||
metadata {
|
||||
name = "media"
|
||||
labels = {
|
||||
managed-by = "terraform"
|
||||
tier = "apps"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user