Files
chemavxandClaude Fable 5 ca520d3ca3 feat(researchowl): daily SQLite backup CronJob + 5Gi backups PVC
Online-safe sqlite3 .backup at 03:00 Europe/Madrid, integrity check,
7-day retention. Data PVC mounted RW (WAL -shm requirement) but only read.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 10:43:41 +00:00

91 lines
2.9 KiB
YAML

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
# Never let ArgoCD prune this PVC: it holds the DB backups.
argocd.argoproj.io/sync-options: Prune=false
name: researchowl-backups
namespace: researchowl
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
# DB is ~220MB and growing; 7 daily copies ≈ 1.6Gi, so 2Gi would fill up.
storage: 5Gi
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: researchowl-db-backup
namespace: researchowl
labels:
app: researchowl
spec:
schedule: "0 3 * * *"
timeZone: "Europe/Madrid"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 2
activeDeadlineSeconds: 600
template:
metadata:
labels:
app: researchowl-db-backup
spec:
restartPolicy: Never
containers:
- name: backup
image: keinos/sqlite3:latest
command:
- /bin/sh
- -c
- |
set -eu
STAMP=$(date +%Y%m%d)
DEST="/backups/researchowl-${STAMP}.db"
echo "Backing up /data/researchowl.db -> ${DEST}"
sqlite3 -cmd ".timeout 30000" /data/researchowl.db ".backup '${DEST}'"
RESULT=$(sqlite3 "${DEST}" "PRAGMA integrity_check;")
if [ "${RESULT}" != "ok" ]; then
echo "Integrity check FAILED: ${RESULT}"
rm -f "${DEST}"
exit 1
fi
echo "Integrity check ok"
# Retention: keep the 7 most recent backups
for f in $(ls -1t /backups/researchowl-*.db | tail -n +8); do
echo "Pruning old backup ${f}"
rm -f "${f}"
done
ls -lh /backups/
volumeMounts:
# NOT readOnly: the source DB runs in WAL mode and sqlite readers
# must be able to touch the -shm/-wal sidecar files. The job only
# ever reads the DB (.backup); it never modifies application data.
- name: data
mountPath: /data
- name: backups
mountPath: /backups
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "500m"
volumes:
# Same RWO local-path PVC as the bot: the PV's node affinity pins this
# pod to the node where the data lives, so co-mounting is safe.
- name: data
persistentVolumeClaim:
claimName: researchowl-data
- name: backups
persistentVolumeClaim:
claimName: researchowl-backups