From 2359970f489faf1e0a63450611c00c28331c3c29 Mon Sep 17 00:00:00 2001 From: Nick Szaunig Date: Mon, 12 Oct 2026 02:04:28 +0200 Subject: [PATCH] feat(k8s): daily pg_dump backup of the database CronJob apicore-db-backup dumps the database to the Storage Box (StorageClass smb-backup, SMB 3.1.1 with seal). Keeps 14 daily and 8 weekly dumps. Co-Authored-By: Claude Opus 5.5 (1M context) --- deploy/k8s/postgres/backup-cronjob.yaml | 76 +++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 deploy/k8s/postgres/backup-cronjob.yaml diff --git a/deploy/k8s/postgres/backup-cronjob.yaml b/deploy/k8s/postgres/backup-cronjob.yaml new file mode 100644 index 0000000..6da44b5 --- /dev/null +++ b/deploy/k8s/postgres/backup-cronjob.yaml @@ -0,0 +1,76 @@ +# Tägliche pg_dump-Sicherung der ApiCore-Datenbank auf die Storage Box. +# Voraussetzung im Cluster: StorageClass smb-backup (SMB 3.1.1 mit seal), +# legt pro PVC einen Ordner unter Server/Backups// an. +# Aufbewahrung: 14 Tage täglich, 8 Wochen sonntags. +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: apicore-db-backup +spec: + accessModes: [ReadWriteMany] + storageClassName: smb-backup + resources: + requests: + storage: 10Gi +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: apicore-db-backup +spec: + schedule: "5 2 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + backoffLimit: 1 + activeDeadlineSeconds: 1800 + template: + metadata: + labels: + app: apicore-db-backup + db-client: "true" + spec: + restartPolicy: Never + automountServiceAccountToken: false + securityContext: + runAsUser: 70 + runAsGroup: 70 + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + containers: + - name: backup + image: postgres:18.6-alpine + command: + - /bin/sh + - -ec + - | + stamp=$(date +%Y-%m-%d) + kind=daily; [ "$(date +%u)" = "7" ] && kind=weekly + mkdir -p /backups/daily /backups/weekly + pg_dump -h apicore-postgres -Fc -f /backups/$kind/apicore-$stamp.dump.tmp + mv /backups/$kind/apicore-$stamp.dump.tmp /backups/$kind/apicore-$stamp.dump + find /backups/daily -name '*.dump' -mtime +14 -delete + find /backups/weekly -name '*.dump' -mtime +56 -delete + ls -l /backups/$kind | tail -3 + env: + - name: PGUSER + valueFrom: {secretKeyRef: {name: apicore-postgres-secret, key: POSTGRES_USER}} + - name: PGPASSWORD + valueFrom: {secretKeyRef: {name: apicore-postgres-secret, key: POSTGRES_PASSWORD}} + - name: PGDATABASE + valueFrom: {secretKeyRef: {name: apicore-postgres-secret, key: POSTGRES_DB}} + resources: + requests: {cpu: "0", memory: "0"} + limits: {memory: 512Mi} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: {drop: [ALL]} + volumeMounts: + - {name: backups, mountPath: /backups} + volumes: + - name: backups + persistentVolumeClaim: {claimName: apicore-db-backup}