{{- if and .Values.backup.enabled (eq .Values.database.driver "postgres") }} apiVersion: batch/v1 kind: CronJob metadata: name: {{ .Release.Name }}-backup labels: {{- include "switchboard.labels" . | nindent 4 }} app.kubernetes.io/component: backup spec: schedule: {{ .Values.backup.schedule | quote }} concurrencyPolicy: Forbid successfulJobsHistoryLimit: {{ .Values.backup.historyLimit | default 3 }} failedJobsHistoryLimit: {{ .Values.backup.failedHistoryLimit | default 1 }} jobTemplate: spec: activeDeadlineSeconds: {{ .Values.backup.activeDeadlineSeconds | default 3600 }} template: metadata: labels: app.kubernetes.io/name: {{ .Chart.Name }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/component: backup spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 12 }} {{- end }} restartPolicy: OnFailure containers: - name: backup image: postgres:16-alpine command: - /bin/sh - -c - | set -e TIMESTAMP=$(date +%Y%m%d-%H%M%S) FILENAME="switchboard-${TIMESTAMP}.sql.gz" echo "Starting backup: ${FILENAME}" pg_dump "${DATABASE_URL}" | gzip > "/backup/${FILENAME}" echo "Backup written: /backup/${FILENAME} ($(du -h /backup/${FILENAME} | cut -f1))" {{- if .Values.backup.s3.enabled }} # Upload to S3-compatible storage apk add --no-cache aws-cli >/dev/null 2>&1 export AWS_ACCESS_KEY_ID="${S3_ACCESS_KEY}" export AWS_SECRET_ACCESS_KEY="${S3_SECRET_KEY}" S3_PATH="s3://{{ .Values.backup.s3.bucket }}/{{ .Values.backup.s3.prefix }}${FILENAME}" aws s3 cp "/backup/${FILENAME}" "${S3_PATH}" \ --endpoint-url "{{ .Values.backup.s3.endpoint }}" \ {{- if .Values.backup.s3.forcePathStyle }} --no-verify-ssl \ {{- end }} --region "{{ .Values.backup.s3.region }}" echo "Uploaded to ${S3_PATH}" {{- end }} # Prune old local backups beyond retention cd /backup ls -t switchboard-*.sql.gz 2>/dev/null | tail -n +{{ add1 .Values.backup.retention }} | xargs -r rm -v echo "Backup complete" env: - name: DATABASE_URL value: {{ include "switchboard.databaseURL" . | quote }} {{- if .Values.backup.s3.enabled }} - name: S3_ACCESS_KEY valueFrom: secretKeyRef: name: {{ include "switchboard.secretName" . }} key: BACKUP_S3_ACCESS_KEY optional: true - name: S3_SECRET_KEY valueFrom: secretKeyRef: name: {{ include "switchboard.secretName" . }} key: BACKUP_S3_SECRET_KEY optional: true {{- end }} {{- if .Values.backup.resources }} resources: {{- toYaml .Values.backup.resources | nindent 16 }} {{- end }} volumeMounts: - name: backup-data mountPath: /backup volumes: - name: backup-data {{- if .Values.backup.persistence.enabled }} persistentVolumeClaim: claimName: {{ .Release.Name }}-backup {{- else }} emptyDir: {} {{- end }} {{- end }}