Example: Postgres backups to Oracle
The generic recipe is in Onboard an app; this page shows it filled in for the Postgres clusters running on Project Loom.
Every on-cluster Postgres database backs up to Oracle Cloud Object Storage via
CloudNativePG’s barmanObjectStore. Continuous
WAL archiving plus a nightly base backup gives
point-in-time recovery across a 30-day window. Not every cluster shares a bucket — penvoice-pg,
keycloak-pg (per env prefix), and infisical-pg write to the same bucket (penvoice-pg-backups, into per-cluster
folders); talon-pg has its own (talon-pg-backups). Sharing a bucket is incidental, not a platform rule.
Backup flow
Section titled “Backup flow”flowchart LR PA[penvoice-pg] -->|WAL + base| B[(s3://penvoice-pg-backups)] KC[keycloak-pg] -->|WAL + base| B INF[infisical-pg] -->|WAL + base| B TA[talon-pg] -->|WAL + base| B2[(s3://talon-pg-backups)] SB1[ScheduledBackup 02:00] -.triggers.-> PA SB2[ScheduledBackup 02:30] -.triggers.-> KC SB3[ScheduledBackup 04:00] -.triggers.-> INF SB4[ScheduledBackup 03:00] -.triggers.-> TA B --> O[Oracle Object Storage af-johannesburg-1] B2 --> O
CNPG namespaces backups under a bucket by cluster name, so one bucket safely holds several clusters’ folders side by side.
The barmanObjectStore config
Section titled “The barmanObjectStore config”Identical on both clusters apart from the credential Secret. From
workloads/penvoice/base/postgres-cluster.yaml (overlay patches the prefix per env):
backup: retentionPolicy: "30d" barmanObjectStore: destinationPath: "s3://penvoice-pg-backups/" endpointURL: "https://axtbyjmrm2rt.compat.objectstorage.af-johannesburg-1.oraclecloud.com" s3Credentials: accessKeyId: name: penvoice-pg-backup-creds key: ACCESS_KEY_ID secretAccessKey: name: penvoice-pg-backup-creds key: ACCESS_SECRET_KEY wal: compression: gzip data: compression: gzipkeycloak-pg uses the same endpoint and keycloak-pg-backup-creds; overlays set
…/keycloak-staging/ or …/keycloak-prod/. WAL and base data are gzip; retention is 30 days.
The scheduled backups
Section titled “The scheduled backups”Each cluster has a ScheduledBackup. CNPG cron is 6-field (seconds first):
| Cluster | ScheduledBackup | Schedule | Time |
|---|---|---|---|
penvoice-pg | penvoice-pg-daily | 0 0 2 * * * | 02:00 daily |
keycloak-pg | keycloak-pg-daily | 0 30 2 * * * | 02:30 daily |
talon-pg | talon-pg-daily | 0 0 3 * * * | 03:00 daily |
infisical-pg | infisical-pg-daily | 0 0 4 * * * | 04:00 daily |
spec: schedule: "0 0 2 * * *" backupOwnerReference: self cluster: name: penvoice-pgA nightly base backup + continuous WAL archiving together provide PITR over the 30-day retention window.
The Oracle S3-compat workaround
Section titled “The Oracle S3-compat workaround”Oracle’s S3-compatible endpoint needed two environment tweaks on each CNPG cluster, set under spec.env:
env: - name: AWS_REQUEST_CHECKSUM_CALCULATION value: when_required - name: AWS_RESPONSE_CHECKSUM_VALIDATION value: when_required - name: AWS_DEFAULT_REGION value: af-johannesburg-1AWS_*_CHECKSUM_CALCULATION=when_required— botocore ≥ 1.36 sends checksum trailers that Oracle returnsNotImplementedfor; this disables them.AWS_DEFAULT_REGION=af-johannesburg-1— signs SigV4 with the bucket’s real region.
:::caution The Customer Secret Key matters: the access key is clean hex, but the secret key contains +/=.
Swapping them puts a / into the SigV4 Credential and breaks header parsing. The keys live in out-of-band Secrets — one
per cluster, e.g. penvoice-pg-backup-creds, keycloak-pg-backup-creds, talon-pg-backup-creds,
infisical-pg-backup-creds (not in git — recreate on rebuild).
:::
:::note CNPG’s in-tree barmanObjectStore is deprecated (works through 1.29, removed in 1.30); the future move is the
Barman Cloud plugin. The platform runs CNPG operator v1.29.1.
:::