Skip to content

Example: Postgres backups to Oracle

The generic recipe is in Onboard an app; this page shows it filled in for the two example Postgres clusters running on Ultron Infra.

Both on-cluster Postgres databases — penvoice-pg (the Penvoice API) and keycloak-test-pg (Keycloak) — back 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. Both clusters write to the same bucket penvoice-pg-backups, into per-cluster folders.

flowchart LR
  PA[penvoice-pg] -->|WAL + base| B[(s3://penvoice-pg-backups)]
  KC[keycloak-test-pg] -->|WAL + base| B
  SB1[ScheduledBackup 02:00] -.triggers.-> PA
  SB2[ScheduledBackup 02:30] -.triggers.-> KC
  B --> O[Oracle Object Storage af-johannesburg-1]

CNPG namespaces backups under the bucket by cluster name, so one bucket safely holds both: penvoice-pg/ and keycloak-test-pg/ folders.

Identical on both clusters apart from the credential Secret. From workloads/penvoice/postgres-cluster.yaml:

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: gzip

keycloak-test-pg uses the same destinationPath and endpointURL but reads its keys from the keycloak-pg-backup-creds Secret. WAL and base data are both gzip-compressed; retention is 30 days.

Each cluster has a ScheduledBackup. CNPG cron is 6-field (seconds first):

ClusterScheduledBackupScheduleTime
penvoice-pgpenvoice-pg-daily0 0 2 * * *02:00 daily
keycloak-test-pgkeycloak-test-pg-daily0 30 2 * * *02:30 daily
spec:
schedule: "0 0 2 * * *"
backupOwnerReference: self
cluster:
name: penvoice-pg

A nightly base backup + continuous WAL archiving together provide PITR over the 30-day retention window.

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-1
  • AWS_*_CHECKSUM_CALCULATION=when_required — botocore ≥ 1.36 sends checksum trailers that Oracle returns NotImplemented for; this disables them.
  • AWS_DEFAULT_REGION=af-johannesburg-1 — signs SigV4 with the bucket’s real region.