--- apiVersion: batch/v1 kind: CronJob metadata: name: stalwart-postgres-backup namespace: stalwart labels: app: stalwart-postgres-backup spec: schedule: "30 2 * * *" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 3 jobTemplate: spec: backoffLimit: 2 activeDeadlineSeconds: 1800 template: metadata: labels: app: stalwart-postgres-backup spec: restartPolicy: OnFailure containers: - name: backup image: postgres:16-alpine imagePullPolicy: IfNotPresent command: - /bin/sh - -c - | set -euo pipefail BACKUP_START=$(date +%s) echo "=== Starting Stalwart Postgres backup at $(date -u) ===" # pg_dump already in image; restic is small and only needed here. apk add --no-cache restic export RESTIC_REPOSITORY="s3:${S3_ENDPOINT}/${S3_BUCKET}/stalwart" echo "Repository: ${RESTIC_REPOSITORY}" # Repo is shared with the RocksDB backup, so it already exists; # init only if the RocksDB side has not created it yet. restic snapshots > /dev/null 2>&1 || restic init echo "Streaming pg_dump | gzip -> restic (tag stalwart-postgres)..." PGPASSWORD="${POSTGRES_PASSWORD}" pg_dump \ -h stalwart-postgres.stalwart.svc.cluster.local \ -U "${POSTGRES_USER}" \ -d "${POSTGRES_DB}" \ --no-owner --no-acl \ | gzip -c \ | restic backup \ --stdin \ --stdin-filename stalwart-postgres.sql.gz \ --tag stalwart-postgres \ --tag daily \ --host stalwart-postgres-k8s echo "Forget/prune (tag=stalwart-postgres, independent retention)..." restic forget \ --tag stalwart-postgres \ --keep-daily 14 \ --keep-weekly 8 \ --keep-monthly 6 \ --prune echo "Latest stalwart-postgres snapshots:" restic snapshots --tag stalwart-postgres --compact || true BACKUP_END=$(date +%s) echo "=== Postgres backup complete in $((BACKUP_END - BACKUP_START))s at $(date -u) ===" env: - name: POSTGRES_USER valueFrom: secretKeyRef: name: stalwart-postgres-credentials key: POSTGRES_USER - name: POSTGRES_DB valueFrom: secretKeyRef: name: stalwart-postgres-credentials key: POSTGRES_DB - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: stalwart-postgres-credentials key: POSTGRES_PASSWORD - name: RESTIC_PASSWORD valueFrom: secretKeyRef: name: stalwart-s3-backup key: restic-password - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: stalwart-s3-backup key: access-key - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: stalwart-s3-backup key: secret-key - name: S3_ENDPOINT valueFrom: secretKeyRef: name: stalwart-s3-backup key: endpoint - name: S3_BUCKET valueFrom: secretKeyRef: name: stalwart-s3-backup key: bucket resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 512Mi