- CronJob: daily-minio-backup, 每天 UTC 3:00 执行 - 备份 SQLite DB 到 minio-api.oci.euphon.net/oil-backups/ - 文件名: oil_calculator_YYYYMMDD.db - 滚动保留最近 30 份,自动删除旧备份 - 使用 Python minio SDK 上传 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
97 lines
3.5 KiB
YAML
97 lines
3.5 KiB
YAML
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: minio-backup-creds
|
|
namespace: oil-calculator
|
|
type: Opaque
|
|
stringData:
|
|
MINIO_ALIAS: "oci"
|
|
MINIO_URL: "https://minio-api.oci.euphon.net"
|
|
MINIO_ACCESS_KEY: "admin"
|
|
MINIO_SECRET_KEY: "HpYMIVH0WN79VkzF4L4z8Zx1"
|
|
MINIO_BUCKET: "oil-backups"
|
|
---
|
|
apiVersion: batch/v1
|
|
kind: CronJob
|
|
metadata:
|
|
name: daily-minio-backup
|
|
namespace: oil-calculator
|
|
spec:
|
|
schedule: "0 3 * * *" # Daily at 3:00 UTC
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 2
|
|
jobTemplate:
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: backup
|
|
image: registry.oci.euphon.net/oil-calculator:latest
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
set -e
|
|
DATE=$(date +%Y%m%d)
|
|
export BACKUP_FILE="oil_calculator_${DATE}.db"
|
|
|
|
echo "=== Oil Calculator Daily Backup ==="
|
|
echo "Date: ${DATE}"
|
|
|
|
# 1. Copy SQLite database (app does WAL checkpoint every 5min)
|
|
cp /data/oil_calculator.db /tmp/${BACKUP_FILE}
|
|
SIZE=$(du -h /tmp/${BACKUP_FILE} | cut -f1)
|
|
echo "Backup created: ${BACKUP_FILE} (${SIZE})"
|
|
|
|
# 2. Upload to minio and cleanup using Python minio SDK
|
|
pip install -q minio 2>/dev/null
|
|
cat > /tmp/upload_backup.py << 'PYEOF'
|
|
import os
|
|
from minio import Minio
|
|
url = os.environ['MINIO_URL'].replace('https://','').replace('http://','')
|
|
client = Minio(url, access_key=os.environ['MINIO_ACCESS_KEY'], secret_key=os.environ['MINIO_SECRET_KEY'], secure='https' in os.environ['MINIO_URL'])
|
|
bucket = os.environ['MINIO_BUCKET']
|
|
bf = os.environ['BACKUP_FILE']
|
|
client.fput_object(bucket, bf, '/tmp/' + bf)
|
|
print('Uploaded:', bf)
|
|
objs = sorted(client.list_objects(bucket, prefix='oil_calculator_'), key=lambda o: o.object_name, reverse=True)
|
|
for o in objs[30:]:
|
|
client.remove_object(bucket, o.object_name)
|
|
print('Deleted:', o.object_name)
|
|
print('Total backups:', min(len(objs), 30))
|
|
PYEOF
|
|
python3 /tmp/upload_backup.py
|
|
echo "=== Done ==="
|
|
env:
|
|
- name: MINIO_URL
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: minio-backup-creds
|
|
key: MINIO_URL
|
|
- name: MINIO_ACCESS_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: minio-backup-creds
|
|
key: MINIO_ACCESS_KEY
|
|
- name: MINIO_SECRET_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: minio-backup-creds
|
|
key: MINIO_SECRET_KEY
|
|
- name: MINIO_BUCKET
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: minio-backup-creds
|
|
key: MINIO_BUCKET
|
|
volumeMounts:
|
|
- name: data
|
|
mountPath: /data
|
|
readOnly: true
|
|
volumes:
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: oil-calculator-data
|
|
restartPolicy: OnFailure
|
|
imagePullSecrets:
|
|
- name: regcred
|