From 167fc62b92712888dff72a53b1d1382918dd03a3 Mon Sep 17 00:00:00 2001 From: Felix Wolf Date: Fri, 3 Apr 2026 17:21:09 +0200 Subject: [PATCH] feat: Add automated backups for Forgejo (Postgres + git repos) - CNPG Barman backup to Hetzner S3 (s3://k8s-and-chill-backups/forgejo/cnpg/) - ScheduledBackup CR: daily at 2 AM, 30d retention, prefer-standby - Git repo rclone sync to S3 (s3://k8s-and-chill-backups/forgejo/git/) via CronJob at 3 AM - Requires secrets: forgejo-backup-s3 (S3 creds), hcloud-token (not used but created) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../argocd/replace-jobs.overlay.ytt.yaml | 8 +- prototypes/forgejo/ytt/cnpg-cluster.ytt.yaml | 18 ++++ .../ytt/cnpg-scheduled-backup.ytt.yaml | 17 ++++ .../forgejo/ytt/git-snapshot-cronjob.ytt.yaml | 87 +++++++++++++++++++ rendered/argocd/production/app-forgejo.yaml | 7 +- .../forgejo/cluster-forgejo-cnpg.yaml | 17 ++++ .../forgejo/cronjob-forgejo-git-backup.yaml | 77 ++++++++++++++++ .../scheduledbackup-forgejo-daily-backup.yaml | 14 +++ .../serviceaccount-forgejo-git-backup.yaml | 7 ++ 9 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 prototypes/forgejo/ytt/cnpg-scheduled-backup.ytt.yaml create mode 100644 prototypes/forgejo/ytt/git-snapshot-cronjob.ytt.yaml create mode 100644 rendered/envs/production/forgejo/cronjob-forgejo-git-backup.yaml create mode 100644 rendered/envs/production/forgejo/scheduledbackup-forgejo-daily-backup.yaml create mode 100644 rendered/envs/production/forgejo/serviceaccount-forgejo-git-backup.yaml diff --git a/envs/production/_apps/forgejo/argocd/replace-jobs.overlay.ytt.yaml b/envs/production/_apps/forgejo/argocd/replace-jobs.overlay.ytt.yaml index 9b986ce..b99c896 100644 --- a/envs/production/_apps/forgejo/argocd/replace-jobs.overlay.ytt.yaml +++ b/envs/production/_apps/forgejo/argocd/replace-jobs.overlay.ytt.yaml @@ -4,8 +4,12 @@ --- #@overlay/match-child-defaults missing_ok=True spec: + ignoreDifferences: + - group: "" + kind: PersistentVolumeClaim + jsonPointers: + - /spec/volumeName syncPolicy: - #@overlay/match missing_ok=True syncOptions: #@overlay/append - - Replace=true + - RespectIgnoreDifferences=true diff --git a/prototypes/forgejo/ytt/cnpg-cluster.ytt.yaml b/prototypes/forgejo/ytt/cnpg-cluster.ytt.yaml index 983cc03..86a9d3d 100644 --- a/prototypes/forgejo/ytt/cnpg-cluster.ytt.yaml +++ b/prototypes/forgejo/ytt/cnpg-cluster.ytt.yaml @@ -27,6 +27,24 @@ spec: limits: memory: 512Mi + backup: + barmanObjectStore: + endpointURL: https://fsn1.your-objectstorage.com + destinationPath: s3://k8s-and-chill-backups/forgejo/cnpg + s3Credentials: + accessKeyId: + name: forgejo-backup-s3 + key: ACCESS_KEY_ID + secretAccessKey: + name: forgejo-backup-s3 + key: SECRET_ACCESS_KEY + wal: + compression: gzip + data: + compression: gzip + retentionPolicy: "30d" + target: prefer-standby + postgresql: parameters: shared_buffers: "64MB" diff --git a/prototypes/forgejo/ytt/cnpg-scheduled-backup.ytt.yaml b/prototypes/forgejo/ytt/cnpg-scheduled-backup.ytt.yaml new file mode 100644 index 0000000..a9947b5 --- /dev/null +++ b/prototypes/forgejo/ytt/cnpg-scheduled-backup.ytt.yaml @@ -0,0 +1,17 @@ +#@ load("@ytt:data", "data") + +#@ ns = data.values.application.namespace + +--- +apiVersion: postgresql.cnpg.io/v1 +kind: ScheduledBackup +metadata: + name: forgejo-daily-backup + namespace: #@ ns +spec: + cluster: + name: forgejo-cnpg + schedule: "0 0 2 * * *" + method: barmanObjectStore + backupOwnerReference: cluster + target: prefer-standby diff --git a/prototypes/forgejo/ytt/git-snapshot-cronjob.ytt.yaml b/prototypes/forgejo/ytt/git-snapshot-cronjob.ytt.yaml new file mode 100644 index 0000000..f0691cb --- /dev/null +++ b/prototypes/forgejo/ytt/git-snapshot-cronjob.ytt.yaml @@ -0,0 +1,87 @@ +#@ load("@ytt:data", "data") + +#@ ns = data.values.application.namespace + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: forgejo-git-backup + namespace: #@ ns + +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: forgejo-git-backup + namespace: #@ ns +spec: + schedule: "0 3 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + ttlSecondsAfterFinished: 86400 + template: + spec: + restartPolicy: OnFailure + serviceAccountName: forgejo-git-backup + nodeSelector: + kubernetes.io/hostname: ubuntu-4gb-nbg1-3 + containers: + - name: backup + image: alpine:3.20 + command: + - sh + - -c + - | + set -e + apk add --no-cache rclone > /dev/null 2>&1 + + mkdir -p /tmp/rclone + cat > /tmp/rclone/rclone.conf < /dev/null 2>&1 + + mkdir -p /tmp/rclone + cat > /tmp/rclone/rclone.conf <