Files
infrastructure/servers/legion/k8s/media/backup-cronjob.yaml
T
Will Anderson 409274ff54 media: add nightly config backup to Cloudflare R2 via restic
Backs up all service config PVCs (Jellyfin, Radarr, Sonarr, Prowlarr,
qBittorrent, Bazarr, Seerr) at 3am daily to legion-media-backup R2 bucket.
Media files are excluded — they are re-downloadable.
2026-04-11 01:22:24 -05:00

116 lines
3.9 KiB
YAML

# Nightly media config backup — backs up all service config PVCs to Cloudflare R2 via restic
# NOTE: Does NOT back up actual media files (movies, TV, etc.) — those are re-downloadable.
# Only backs up app configs: Jellyfin, Radarr, Sonarr, Sonarr, Prowlarr, qBittorrent, Bazarr, Seerr.
# Schedule: 3am daily (offset from Gitea backup at 2am)
# Retains: 30 daily / 12 weekly / 6 monthly snapshots
apiVersion: batch/v1
kind: CronJob
metadata:
name: media-backup
namespace: media
spec:
schedule: "0 3 * * *"
concurrencyPolicy: Forbid
failedJobsHistoryLimit: 3
successfulJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 2
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: restic/restic:latest
command:
- /bin/sh
- -c
- |
set -e
# Init repo if first run
restic snapshots 2>/dev/null || restic init
echo "Backing up media service configs..."
restic backup \
/jellyfin-config \
/radarr-config \
/sonarr-config \
/prowlarr-config \
/qbittorrent-config \
/bazarr-config \
/overseerr-config \
--tag media \
--tag legion \
--host legion
# Prune old snapshots
restic forget \
--keep-daily 30 \
--keep-weekly 12 \
--keep-monthly 6 \
--prune
echo "Backup complete."
restic snapshots --latest 3
envFrom:
- secretRef:
name: media-backup-credentials
volumeMounts:
- name: jellyfin-config
mountPath: /jellyfin-config
readOnly: true
- name: radarr-config
mountPath: /radarr-config
readOnly: true
- name: sonarr-config
mountPath: /sonarr-config
readOnly: true
- name: prowlarr-config
mountPath: /prowlarr-config
readOnly: true
- name: qbittorrent-config
mountPath: /qbittorrent-config
readOnly: true
- name: bazarr-config
mountPath: /bazarr-config
readOnly: true
- name: overseerr-config
mountPath: /overseerr-config
readOnly: true
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 512Mi
volumes:
- name: jellyfin-config
persistentVolumeClaim:
claimName: jellyfin-config
readOnly: true
- name: radarr-config
persistentVolumeClaim:
claimName: radarr-config
readOnly: true
- name: sonarr-config
persistentVolumeClaim:
claimName: sonarr-config
readOnly: true
- name: prowlarr-config
persistentVolumeClaim:
claimName: prowlarr-config
readOnly: true
- name: qbittorrent-config
persistentVolumeClaim:
claimName: qbittorrent-config
readOnly: true
- name: bazarr-config
persistentVolumeClaim:
claimName: bazarr-config
readOnly: true
- name: overseerr-config
persistentVolumeClaim:
claimName: overseerr-config
readOnly: true