apiVersion: batch/v1 kind: CronJob metadata: name: planner-backup-minio namespace: planner spec: schedule: "0 */6 * * *" successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 3 jobTemplate: spec: template: spec: containers: - name: backup image: python:3.12-alpine command: - /bin/sh - -c - | apk add --no-cache curl sqlite >/dev/null 2>&1 curl -sL https://dl.min.io/client/mc/release/linux-arm64/mc -o /usr/local/bin/mc chmod +x /usr/local/bin/mc mc alias set s3 http://minio.minio.svc:9000 admin HpYMIVH0WN79VkzF4L4z8Zx1 TS=$(date +%Y%m%d_%H%M%S) # SQLite safe backup sqlite3 /data/planner.db ".backup /tmp/planner_${TS}.db" mc cp "/tmp/planner_${TS}.db" "s3/planner-backups/planner_${TS}.db" # Keep only last 60 backups mc ls s3/planner-backups/ --json | python3 -c " import sys, json files = [] for line in sys.stdin: d = json.loads(line) if d.get('key','').startswith('planner_'): files.append(d['key']) files.sort() for f in files[:-60]: print(f) " | while read f; do mc rm "s3/planner-backups/$f"; done echo "Backup done: ${TS}" volumeMounts: - name: data mountPath: /data readOnly: true volumes: - name: data persistentVolumeClaim: claimName: planner-data restartPolicy: OnFailure