apiVersion: batch/v1 kind: CronJob metadata: name: nextcloud-nfs-backup namespace: nextcloud spec: schedule: "0 2 * * *" # Every day at 2:00 AM concurrencyPolicy: Forbid # Prevent a second job from starting if the first is still running successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 5 jobTemplate: spec: template: spec: restartPolicy: OnFailure containers: - name: restic image: restic/restic:0.16.4 imagePullPolicy: IfNotPresent envFrom: - secretRef: name: nextcloud-backup-secrets command: - /bin/sh - -c - | set -e echo "Checking if Restic repository is initialized..." if ! restic snapshots >/dev/null 2>&1; then echo "Repository not found. Initializing..." restic init fi echo "Starting backup of Nextcloud user data..." restic backup /data --verbose echo "Enforcing retention policy (Pruning old snapshots)..." restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune echo "Backup lifecycle complete!" volumeMounts: - name: target-data mountPath: /data readOnly: true volumes: - name: target-data persistentVolumeClaim: claimName: nextcloud-media-nfs-pvc --- apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: nextcloud-backup-secrets namespace: nextcloud spec: refreshInterval: "1h" secretStoreRef: name: vault-external-secrets-store kind: ClusterSecretStore target: name: nextcloud-backup-secrets creationPolicy: Owner data: - secretKey: B2_ACCOUNT_ID remoteRef: key: nextcloud/b2 property: key-id - secretKey: B2_ACCOUNT_KEY remoteRef: key: nextcloud/b2 property: application-key - secretKey: RESTIC_REPOSITORY remoteRef: key: nextcloud/b2 property: restic-repository - secretKey: RESTIC_PASSWORD remoteRef: key: nextcloud/b2 property: restic-password