Cloud Native PostgreSQL (Legacy)¶
The following text is a description of the old way of creating a database cluster and backups with CloudNative PostgreSQL. We strongly recommend you use the newer method described in postgresql.md, but provide the docs for the legacy method for now.
Example Cluster (Legacy)¶
Create the S3 Bucket¶
Create a Bucket in an Exoscale zone that is NOT at-vie-1 by following the instructions:
apiVersion: appcat.vshn.io/v1
kind: ObjectBucket
metadata:
name: <project>-s3-bucket-pgbackup
namespace: aris-<project>
spec:
parameters:
bucketName: <project>-s3-bucket-pgbackup
region: at-vie-2
writeConnectionSecretToRef:
name: <project>-s3-bucket-pgbackup
This creates a bucket in Exoscale region at-vie-2 and writes the connection information to a secret, that can then be used
by PostgreSQL.
Create the Database¶
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
namespace: aris-<project>
name: <project>-db
spec:
description: "Postgres cluster for <project>"
imageName: ghcr.io/cloudnative-pg/postgresql:17.5
instances: 3
primaryUpdateStrategy: unsupervised
startDelay: 300
stopDelay: 300
monitoring:
enablePodMonitor: true
# Persistent storage configuration
storage:
storageClass: rbd-storagepool-cluster
size: 2Gi
postgresql:
parameters:
max_slot_wal_keep_size: "1GB"
bootstrap:
initdb:
database: xxx
owner: xxx
resources:
requests:
memory: "500Mi"
cpu: "100m" # should be 2
limits:
memory: "2Gi"
affinity:
enablePodAntiAffinity: true #default value
topologyKey: kubernetes.io/hostname #default value
podAntiAffinityType: required
backup:
barmanObjectStore:
destinationPath: s3://<project>-s3-bucket-pgbackup/
endpointURL: https://sos-at-vie-2.exo.io
s3Credentials:
accessKeyId:
name: <project>-s3-bucket-pgbackup
key: AWS_ACCESS_KEY_ID
secretAccessKey:
name: <project>-s3-bucket-pgbackup
key: AWS_SECRET_ACCESS_KEY
wal:
compression: gzip
data:
compression: gzip
jobs: 2
retentionPolicy: "30d"
This will create 3 PostgreSQL Pods with their respective storage volumes. One of the Pods will be the primary database node, the others are followers.
Services for read-write and readonly connections are automatically created by the operator.
Backup the database¶
The YAML from above will create a database and backups of the write ahead logfiles (WAL). To restore the database from this backup you will need every WAL ever written.
We therefore recommend you create a backup schedule, e.g. backup your database by creating a ScheduledBackup custom resource:
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: <project>-db-scheduledbackup
namespace: aris-<project>
spec:
backupOwnerReference: self
cluster:
name: <project>-db
method: barmanObjectStore
schedule: 0 30 21 * * *
target: primary
Use the database¶
You can find the information necessary to connect to your newly created database inside a secret created in your namespace.
Restore the database¶
So, you made a mistake, lost some data or want to create a copy of your database? Time for a restore from backup.
The following way of restoring a database is tried and tested. It creates a restore of the database to a new cluster, that can then be tested or used directly without touching the old database.
Step 1: Create a new S3 Bucket¶
See above. CloudnativePG refuses to use a Bucket, that is not completely empty, so create a new one. Use a different name for the Bucket, e.g. <project>-s3-bucket-pgbackup-new. This is actually not a very good name, but you know, naming things... As mentioned it is wise to create the Bucket in an Exoscale zone that is not at-vie-1.
Step 2: Create a new Database¶
The YAML manifest for creating a new database that restores automatically from a backup contains the same options for storage, PostgreSQL configuration, resource requests etc., but instead of starting the database with the initdb bootstrap stanza, we add the old backup S3 Bucket as a "External Cluster" source for the data and a new name. The following manifest is an abridged version of the code above with the relevant changes:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
namespace: aris-<project>
name: <project>-db-new
spec:
[...]
bootstrap:
recovery:
source: <project>-olddb
recoveryTarget:
targetTime: "2025-12-11 18:00:00.00000+02"
externalClusters:
- name: <project>-olddb
barmanObjectStore:
destinationPath: s3://<project>-s3-bucket-pgbackup/
endpointURL: https://sos-at-vie-2.exo.io
s3Credentials:
accessKeyId:
name: <project>-s3-bucket-pgbackup
key: AWS_ACCESS_KEY_ID
secretAccessKey:
name: <project>-s3-bucket-pgbackup
key: AWS_SECRET_ACCESS_KEY
[...]
backup:
barmanObjectStore:
destinationPath: s3://<project>-s3-bucket-pgbackup-new/
endpointURL: https://sos-at-vie-2.exo.io
s3Credentials:
accessKeyId:
name: <project>-s3-bucket-pgbackup-new
key: AWS_ACCESS_KEY_ID
secretAccessKey:
name: <project>-s3-bucket-pgbackup-new
key: AWS_SECRET_ACCESS_KEY
wal:
compression: gzip
data:
compression: gzip
jobs: 2
retentionPolicy: "30d"
Step 3: Create a new Backup ScheduledBackups¶
See above, but adjust for the new database name and S3 Bucket.
The whole procedure will perform a restore of the old <project>-db database using the backups and WAL files stored in the Bucket <project>-s3-bucket-pgbackup. The new database will be called <project>-db-new and it will immediately start creating WAL backups and follow the schedule for creating ScheduledBackups.
Step 4: Use the restored database and clean up after yourself¶
Test your new database! Make sure it contains the data you want and only proceed if that is actually the case.
Depending on your use case, you might want to delete the old one. If you do so, don't forget to also delete the ScheduledBackup for the old database, as this one now has no target any more.
You can now also delete the old S3 Bucket.