Database & migrations
If <app> needs Postgres, CNPG (the
operator installed cluster-wide in the cnpg-system namespace)
provisions it from a Cluster CR. CNPG auto-generates an
application Secret whose uri key is the connection
string — the app and the migrations Job both read DB_URL from it.
flowchart LR Cluster[CNPG Cluster<br/>app-pg] -->|auto-creates| Secret[(Secret<br/>app-pg-app)] Secret -->|uri → DB_URL| Job[migrations Job<br/>PreSync hook] Secret -->|uri → DB_URL| Rollout[Rollout pods] Job -->|runs first| Rollout Cluster -->|WAL + base backup| OOS[(Object Storage)]
CNPG Cluster
Section titled “CNPG Cluster”Single instance (one node, no HA). bootstrap.initdb creates the database and an
owner role; CNPG then creates the <app>-pg-app secret. The env and backup blocks
configure WAL archiving + base backups to Oracle Object Storage
(S3-compatible).
apiVersion: postgresql.cnpg.io/v1kind: Clustermetadata: name: <app>-pg namespace: <app>spec: instances: 1
# Oracle S3-compat backups: disable AWS SDK checksum trailers (Oracle returns # NotImplemented) and sign with the bucket's real region. env: - name: AWS_REQUEST_CHECKSUM_CALCULATION value: when_required - name: AWS_RESPONSE_CHECKSUM_VALIDATION value: when_required - name: AWS_DEFAULT_REGION value: <region>
storage: size: 5Gi storageClass: local-path # k3s default (node-local disk)
bootstrap: initdb: database: <app> owner: <app>
resources: requests: cpu: 100m memory: 256Mi limits: memory: 512Mi
# Continuous backup + WAL archiving to Object Storage; creds in Secret # <app>-pg-backup-creds (created out of band — see Secrets). backup: retentionPolicy: "30d" barmanObjectStore: destinationPath: "s3://<bucket>/" endpointURL: "https://<os-namespace>.compat.objectstorage.<region>.oraclecloud.com" s3Credentials: accessKeyId: name: <app>-pg-backup-creds key: ACCESS_KEY_ID secretAccessKey: name: <app>-pg-backup-creds key: ACCESS_SECRET_KEY wal: compression: gzip data: compression: gzipThe <app>-pg-backup-creds secret is created by hand (Oracle Customer Secret Key) —
see Secrets. barmanObjectStore is deprecated upstream (removed
in CNPG 1.30); migrate to the Barman Cloud plugin later.
Nightly base backup
Section titled “Nightly base backup”Pair the cluster with a ScheduledBackup so WAL archiving + a nightly base gives PITR
across the retention window. CNPG cron is 6-field (seconds first).
apiVersion: postgresql.cnpg.io/v1kind: ScheduledBackupmetadata: name: <app>-pg-daily namespace: <app>spec: schedule: "0 0 2 * * *" # 02:00 daily backupOwnerReference: self cluster: name: <app>-pgReading DB_URL from the auto-generated secret
Section titled “Reading DB_URL from the auto-generated secret”CNPG creates Secret/<app>-pg-app automatically. Its uri key holds a ready-to-use
connection string — wire it straight into DB_URL:
env: - name: DB_URL valueFrom: secretKeyRef: name: <app>-pg-app # auto-created by CNPG from the Cluster name key: uriYou never write this secret yourself, and it never goes in Git. The same secretKeyRef
is used in both the Rollout (from GitOps & deploy) and
the migrations Job below.
Migrations as a PreSync hook
Section titled “Migrations as a PreSync hook”Run schema migrations before new pods start, using the migrate CLI bundled into
the image (from Build & CI). The Argo CD PreSync hook
ordering guarantees migrations complete before the Rollout updates; hook-delete-policy: BeforeHookCreation cleans up the previous run.
apiVersion: batch/v1kind: Jobmetadata: name: <app>-migrate namespace: <app> annotations: argocd.argoproj.io/hook: PreSync argocd.argoproj.io/hook-delete-policy: BeforeHookCreationspec: backoffLimit: 3 activeDeadlineSeconds: 300 template: metadata: labels: app: <app>-migrate spec: restartPolicy: Never containers: - name: migrate image: ghcr.io/<owner>/<app>:sha-XXXXXXX command: ["/app/migrate"] args: ["-path", "/app/migrations", "-database", "$(DB_URL)", "up"] env: - name: DB_URL valueFrom: secretKeyRef: name: <app>-pg-app key: uriKeep the Job’s image tag in lockstep with the Rollout’s tag so migrations and code ship together.
Canary & metrics — expose /metrics and gate the
canary on the success rate.