apiVersion: batch/v1 kind: CronJob metadata: name: forgejo-backup namespace: forgejo labels: app: forgejo-backup spec: schedule: "0 3 * * *" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 7 failedJobsHistoryLimit: 3 jobTemplate: spec: template: spec: restartPolicy: OnFailure containers: - name: forgejo-backup image: postgres:16-alpine imagePullPolicy: IfNotPresent command: - /bin/sh - -lc - | set -euo pipefail ts=$(date -u +%Y%m%dT%H%M%SZ) BACKUP_DIR="/data/forgejo-${ts}" mkdir -p "${BACKUP_DIR}" echo "[${ts}] Starting Forgejo backup..." # Backup PostgreSQL database echo "[$(date -u +%H:%M:%S)] Dumping PostgreSQL database..." PGPASSWORD="${POSTGRES_PASSWORD}" pg_dump \ -h forgejo-postgres.forgejo.svc.cluster.local \ -U "${POSTGRES_USER}" \ -d "${POSTGRES_DB}" \ -F c \ -f "${BACKUP_DIR}/forgejo-db.dump" echo "[$(date -u +%H:%M:%S)] Database backup complete: $(ls -lh ${BACKUP_DIR}/forgejo-db.dump | awk '{print $5}')" # Create backup manifest echo "backup_timestamp=${ts}" > "${BACKUP_DIR}/manifest.txt" echo "type=postgresql_custom_dump" >> "${BACKUP_DIR}/manifest.txt" echo "database=forgejo" >> "${BACKUP_DIR}/manifest.txt" echo "restore_cmd=PGPASSWORD= pg_restore -h -U forgejo -d forgejo -F c forgejo-db.dump" >> "${BACKUP_DIR}/manifest.txt" # Cleanup old backups (keep 14 days) find /data -maxdepth 1 -type d -name "forgejo-*" -mtime +14 -exec rm -rf {} + 2>/dev/null || true echo "[$(date -u +%H:%M:%S)] Backup complete. Files:" ls -lh "${BACKUP_DIR}/" echo "[$(date -u +%H:%M:%S)] All backups in storage:" ls -1 /data | grep "forgejo-" env: - name: POSTGRES_USER valueFrom: secretKeyRef: name: forgejo-postgres-secret key: POSTGRES_USER - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: forgejo-postgres-secret key: POSTGRES_PASSWORD - name: POSTGRES_DB valueFrom: secretKeyRef: name: forgejo-postgres-secret key: POSTGRES_DB volumeMounts: - name: backup-data mountPath: /data volumes: - name: backup-data persistentVolumeClaim: claimName: platform-backup-data