Examples ======== The examples show configuration files for setting up your PostgreSQL cluster. .. Note [Important]:: These examples are for demonstration and experimentation purposes. You can execute them on a personal Kubernetes cluster with Minikube or Kind, as described in :ref:`Quick start ` . .. Note [Reference]:: For a list of available options, see :ref:`API Reference ` . Basics ------ **Basic cluster** :ref:`cluster-example.yaml ` A basic example of a cluster. **Custom cluster** :ref:`cluster-example-custom.yaml ` A basic cluster that uses the default storage class and custom parameters for the ``postgresql.conf`` and ``pg_hba.conf`` files. **Cluster with dynamic pg_hba address resolution** :ref:`cluster-example-pod-selector-refs.yaml ` A cluster that uses ``podSelectorRefs`` to dynamically resolve pod IPs in ``pg_hba`` rules via the ``${podselector:NAME}`` syntax. **Cluster with customized storage class** :ref:`cluster-storage-class.yaml ` : A basic cluster that uses a specified storage class of ``standard`` . **Cluster with persistent volume claim (PVC) template configured** :ref:`cluster-pvc-template.yaml ` : A basic cluster with an explicit persistent volume claim template. **Extended configuration example** :ref:`cluster-example-full.yaml ` : A cluster that sets most of the available options. **Bootstrap cluster with SQL files** :ref:`cluster-example-initdb-sql-refs.yaml ` : A cluster example that executes a set of queries defined in a secret and a ``ConfigMap`` right after the database is created. **Sample cluster with customized ``pg_hba`` configuration** :ref:`cluster-example-pg-hba.yaml ` : A basic cluster that enables the user app to authenticate using certificates. **Sample cluster with Secret and ConfigMap mounted using projected volume template** :ref:`cluster-example-projected-volume.yaml ` A basic cluster with the existing ``Secret`` and ``ConfigMap`` mounted into Postgres pod using projected volume mount. Security -------- **Sample cluster with custom security contexts** :ref:`cluster-example-security-context.yaml ` A cluster demonstrating how to customize both Pod and Container security contexts. This is useful when working with Pod Security Standards or meeting specific security requirements. Backups ------- **Customized storage class and backups** *Prerequisites*: Bucket storage must be available. The sample config is for AWS. Change it to suit your setup. :ref:`cluster-storage-class-with-backup.yaml ` A cluster with backups configured. **Backup** *Prerequisites*: :ref:`cluster-storage-class-with-backup.yaml ` applied and healthy. :ref:`backup-example.yaml ` : An example of a backup that runs against the previous sample. **Simple cluster with backup configured for minio** *Prerequisites*: The configuration assumes minio is running and working. Update ``backup.barmanObjectStore`` with your minio parameters or your cloud solution. :ref:`cluster-example-with-backup.yaml ` A basic cluster with backups configured. **Simple cluster with backup configured for Scaleway Object Storage** *Prerequisites*: The configuration assumes a Scaleway Object Storage bucket exists. Update ``backup.barmanObjectStore`` with your Scaleway parameters. :ref:`cluster-example-with-backup-scaleway.yaml ` A basic cluster with backups configured to work with Scaleway Object Storage.. Replica clusters ---------------- **Replica cluster by way of backup from an object store** *Prerequisites*: :ref:`cluster-storage-class-with-backup.yaml ` applied and healthy, and a backup :ref:`cluster-example-trigger-backup.yaml ` applied and completed. :ref:`cluster-example-replica-from-backup-simple.yaml ` : A replica cluster following a cluster with backup configured. **Replica cluster by way of volume snapshot** *Prerequisites*: :ref:`cluster-example-with-volume-snapshot.yaml ` applied and healthy, and a volume snapshot :ref:`backup-with-volume-snapshot.yaml ` applied and completed. :ref:`cluster-example-replica-from-volume-snapshot.yaml ` : A replica cluster following a cluster with volume snapshot configured. **Replica cluster by way of streaming (pg_basebackup)** *Prerequisites*: :ref:`cluster-example.yaml ` applied and healthy. :ref:`cluster-example-replica-streaming.yaml ` : A replica cluster following ``cluster-example`` with streaming replication. PostGIS ------- **PostGIS example with image volume extensions** :ref:`postgis-example.yaml ` : An example of a PostGIS cluster using image volume extensions. See :ref:`PostGIS clusters ` for details. Managed roles ------------- **Cluster with declarative role management** :ref:`cluster-example-with-roles.yaml ` : Declares a role with the ``managed`` stanza. Includes password management with Kubernetes secrets. Managed services ---------------- **Cluster with managed services** :ref:`cluster-example-managed-services.yaml ` : Declares a service with the ``managed`` stanza. Includes default service disabled and new ``rw`` service template of ``LoadBalancer`` type defined. Declarative tablespaces ----------------------- **Cluster with declarative tablespaces** :ref:`cluster-example-with-tablespaces.yaml ` **Cluster with declarative tablespaces and backup** *Prerequisites*: The configuration assumes minio is running and working. Update ``backup.barmanObjectStore`` with your minio parameters or your cloud solution. :ref:`cluster-example-with-tablespaces-backup.yaml ` **Restored cluster with tablespaces from object store** *Prerequisites*: The previous cluster applied and a base backup completed. Remember to update ``bootstrap.recovery.backup.name`` with the backup name. :ref:`cluster-restore-with-tablespaces.yaml ` For a list of available options, see :ref:`API Reference ` . Pooler configuration -------------------- **Pooler with custom service config** :ref:`pooler-external.yaml ` Logical replication via declarative Publication and Subscription objects ------------------------------------------------------------------------ Two test manifests contain everything needed to set up logical replication: **Source cluster with a publication** :ref:`cluster-example-logical-source.yaml ` Sets up a cluster, ``cluster-example`` with some tables created in the ``app`` database, and, importantly, *adds replication to the app user*. A publication is created for the cluster on the ``app`` database: note that the publication will be reconciled only after the cluster’s primary is up and running. **Destination cluster with a subscription** *Prerequisites*: The source cluster with publication, defined as above. :ref:`cluster-example-logical-destination.yaml ` Sets up a cluster ``cluster-example-dest`` with: - the source cluster defined in the ``externalClusters`` stanza. Note that it uses the ``app`` role to connect, which assumes the source cluster grants it ``replication`` privilege. - a bootstrap import of microservice type, with ``schemaOnly`` enabled A subscription is created on the destination cluster: note that the subscription will be reconciled only after the destination cluster’s primary is up and running. After both clusters have been reconciled, together with the publication and subscription objects, you can verify that that tables in the source cluster, and the data in them, have been replicated in the destination cluster In addition, there are some standalone example manifests: **A plain Publication targeting All Tables** *Prerequisites*: an existing cluster ``cluster-example`` . :ref:`publication-example.yaml ` **A Publication with a constrained publication target** *Prerequisites*: an existing cluster ``cluster-example`` . :ref:`publication-example-objects.yaml ` **A plain Subscription** Prerequisites: an existing cluster ``cluster-example`` set up as source, with a publication ``pub-all`` . A cluster ``cluster-example-dest`` set up as a destination cluster, including the ``externalClusters`` stanza with connection parameters to the source cluster, including a role with replication privilege. :ref:`subscription-example.yaml ` All the above manifests create publications or subscriptions on the ``app`` database. The Database CRD offers a convenient way to create databases declaratively. With it, logical replication could be set up for arbitrary databases. Which brings us to the next section. Declarative management of Postgres databases -------------------------------------------- **A plain Database** *Prerequisites*: an existing cluster ``cluster-example`` . :ref:`database-example.yaml ` **A Database with ICU local specifications** *Prerequisites*: an existing cluster ``cluster-example`` running Postgres 16 or more advanced. :ref:`database-example-icu.yaml ` cluster-example.yaml ^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example spec: instances: 3 storage: size: 1Gi cluster-example-custom.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-custom spec: instances: 3 # Parameters and pg_hba configuration will be append # to the default ones to make the cluster work postgresql: parameters: max_worker_processes: "60" pg_hba: # To access through TCP/IP you will need to get username # and password from the secret cluster-example-custom-app - host all all all md5 # Example of rolling update strategy: # - unsupervised: automated update of the primary once all # replicas have been upgraded (default) # - supervised: requires manual supervision to perform # the switchover of the primary primaryUpdateStrategy: unsupervised # Require 1Gi of space per instance using default storage class storage: size: 1Gi cluster-example-pod-selector-refs.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-pod-selector-refs spec: instances: 3 # Define named pod label selectors for dynamic pg_hba address resolution. # The operator resolves matching pod IPs and expands ${podselector:NAME} # references in pg_hba rules into one line per IP with /32 (IPv4) or /128 (IPv6) masks. podSelectorRefs: - name: app-pods selector: matchLabels: app: myapp - name: monitoring selector: matchLabels: role: monitoring postgresql: pg_hba: # These rules use ${podselector:NAME} syntax to reference podSelectorRefs. # Each reference is expanded to one line per matching pod IP. - "hostssl mydb myuser ${podselector:app-pods} scram-sha-256" - "hostssl postgres monitor ${podselector:monitoring} scram-sha-256" # Standard rules without expansion are passed through unchanged. - host all all 10.244.0.0/16 md5 primaryUpdateStrategy: unsupervised storage: size: 1Gi cluster-storage-class.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: postgresql-storage-class spec: instances: 3 # Example of rolling update strategy: # - unsupervised: automated update of the primary once all # replicas have been upgraded (default) # - supervised: requires manual supervision to perform # the switchover of the primary primaryUpdateStrategy: unsupervised # Persistent storage configuration storage: storageClass: standard size: 1Gi cluster-pvc-template.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: postgresql-pvc-template spec: instances: 3 # Example of rolling update strategy: # - unsupervised: automated update of the primary once all # replicas have been upgraded (default) # - supervised: requires manual supervision to perform # the switchover of the primary primaryUpdateStrategy: unsupervised # Persistent storage configuration storage: size: 1Gi pvcTemplate: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: standard volumeMode: Filesystem cluster-example-full.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml # Example of definition of a test cluster using all the elements available # in the CRD. Please change values appropriately for your environment. # Remember that you can take advantage of convention over configuration # and normally you dont need to use all these definitions. apiVersion: v1 data: password: VHhWZVE0bk44MlNTaVlIb3N3cU9VUlp2UURhTDRLcE5FbHNDRUVlOWJ3RHhNZDczS2NrSWVYelM1Y1U2TGlDMg== username: YXBw kind: Secret metadata: name: cluster-example-app-user type: kubernetes.io/basic-auth - -- apiVersion: v1 data: password: dU4zaTFIaDBiWWJDYzRUeVZBYWNCaG1TemdxdHpxeG1PVmpBbjBRSUNoc0pyU211OVBZMmZ3MnE4RUtLTHBaOQ== username: cG9zdGdyZXM= kind: Secret metadata: name: cluster-example-superuser type: kubernetes.io/basic-auth - -- apiVersion: v1 kind: Secret metadata: name: backup-creds data: ACCESS_KEY_ID: a2V5X2lk ACCESS_SECRET_KEY: c2VjcmV0X2tleQ== - -- apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-full spec: description: "Example of cluster" imageName: ghcr.io/cloudnative-pg/postgresql:18.3-system-trixie # imagePullSecret is only required if the images are located in a private registry # imagePullSecrets: # - name: private_registry_access instances: 3 startDelay: 300 stopDelay: 300 primaryUpdateStrategy: unsupervised postgresql: parameters: shared_buffers: 256MB pg_stat_statements.max: 10000 pg_stat_statements.track: all auto_explain.log_min_duration: 10s pg_hba: - host all all 10.244.0.0/16 md5 bootstrap: initdb: database: app owner: app secret: name: cluster-example-app-user # Alternative bootstrap method: start from a backup #recovery: # backup: # name: backup-example enableSuperuserAccess: true superuserSecret: name: cluster-example-superuser storage: storageClass: standard size: 1Gi backup: barmanObjectStore: destinationPath: s3://cluster-example-full-backup/ endpointURL: http://custom-endpoint:1234 s3Credentials: accessKeyId: name: backup-creds key: ACCESS_KEY_ID secretAccessKey: name: backup-creds key: ACCESS_SECRET_KEY wal: compression: gzip encryption: AES256 data: compression: gzip encryption: AES256 immediateCheckpoint: false jobs: 2 retentionPolicy: "30d" resources: requests: memory: "512Mi" cpu: "1" limits: memory: "1Gi" cpu: "2" affinity: enablePodAntiAffinity: true topologyKey: failure-domain.beta.kubernetes.io/zone nodeMaintenanceWindow: inProgress: false reusePVC: false cluster-example-initdb-sql-refs.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: v1 kind: ConfigMap metadata: name: post-init-sql-configmap data: configmap.sql: | create table configmaps (i integer); insert into configmaps (select generate_series(1,10000)); - -- apiVersion: v1 kind: Secret metadata: name: post-init-sql-secret stringData: secret.sql: | create table secrets (i integer); insert into secrets (select generate_series(1,10000)); - -- apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-initdb spec: instances: 3 bootstrap: initdb: database: appdb owner: appuser postInitSQL: - create table numbers (i integer) - insert into numbers (select generate_series(1,10000)) postInitTemplateSQL: - create extension intarray postInitApplicationSQL: - create table application_numbers (i integer) - insert into application_numbers (select generate_series(1,10000)) postInitApplicationSQLRefs: configMapRefs: - name: post-init-sql-configmap key: configmap.sql secretRefs: - name: post-init-sql-secret key: secret.sql storage: size: 1Gi cluster-example-pg-hba.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example spec: instances: 3 postgresql: pg_hba: - hostssl app all all cert storage: size: 1Gi cluster-example-projected-volume.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-projected-volume spec: instances: 3 projectedVolumeTemplate: sources: - secret: name: sample-secret items: - key: tls.crt path: certificate/tls.crt - key: tls.key path: certificate/tls.key - configMap: name: sample-configmap items: - key: key1 path: config/key1 - key: key2 path: config/key2 storage: size: 1Gi - -- apiVersion: v1 data: tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQekNDQWVXZ0F3SUJBZ0lRSHVDY2lKcDVkZis0dHZBcDBrTk9rekFLQmdncWhrak9QUVFEQWpCTk1TTXcKSVFZRFZRUUxFeHB3YjNOMFozSmxjM0ZzTFc5d1pYSmhkRzl5TFhONWMzUmxiVEVtTUNRR0ExVUVBeE1kY0c5egpkR2R5WlhOeGJDMXZjR1Z5WVhSdmNpMWpZUzF6WldOeVpYUXdIaGNOTWpJd09USTVNRGMxTVRBNVdoY05Nakl4Ck1qSTRNRGMxTVRBNVdqQk5NVXN3U1FZRFZRUURFMEp3YjNOMFozSmxjM0ZzTFc5d1pYSmhkRzl5TFhkbFltaHYKYjJzdGMyVnlkbWxqWlM1d2IzTjBaM0psYzNGc0xXOXdaWEpoZEc5eUxYTjVjM1JsYlM1emRtTXdXVEFUQmdjcQpoa2pPUFFJQkJnZ3Foa2pPUFFNQkJ3TkNBQVJRd2lhUm0wSmN4TzlBVlE0MVlqVlRqNUhDSVVFblFQOXNZRXFKCmYvNE1mVm53NkdDOThjNDNmQTVuS2UwSnQ5ZEV3QXREYktkdkRoeDlUTmIzdVY0K280R21NSUdqTUE0R0ExVWQKRHdFQi93UUVBd0lEcURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFUQU1CZ05WSFJNQkFmOEVBakFBTUI4RwpBMVVkSXdRWU1CYUFGQjN6cUVKbWFORENoRDdkWGptSWRlNEhUY0pFTUUwR0ExVWRFUVJHTUVTQ1FuQnZjM1JuCmNtVnpjV3d0YjNCbGNtRjBiM0l0ZDJWaWFHOXZheTF6WlhKMmFXTmxMbkJ2YzNSbmNtVnpjV3d0YjNCbGNtRjAKYjNJdGMzbHpkR1Z0TG5OMll6QUtCZ2dxaGtqT1BRUURBZ05JQURCRkFpQkMwS2M5WWxYelBpL0lhTkRnWHkwawpYTDJpNlZzSHRORTFxN3MzWXh6Mm53SWhBS2IxUW5EVTlqRnNVK0l5a292TitVU1ZpVm5vU2MvZ2RXWkxmMnhoCjZ2WUsKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= tls.key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUtucWxVQjFqU2sxWW5VZzAyb0tGbXlRdDJLUEZwaFc0K1lmQUFmUFdRenVvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFVU1JbWtadENYTVR2UUZVT05XSTFVNCtSd2lGQkowRC9iR0JLaVgvK0RIMVo4T2hndmZITwpOM3dPWnludENiZlhSTUFMUTJ5bmJ3NGNmVXpXOTdsZVBnPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo= kind: Secret metadata: name: sample-secret type: kubernetes.io/tls - -- apiVersion: v1 data: key1: value1 key2: value2 key3: value3 kind: ConfigMap metadata: name: sample-configmap cluster-example-security-context.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml # Example of PostgreSQL cluster with custom security contexts # # This example demonstrates how to customize both PodSecurityContext and # Container SecurityContext for a PostgreSQL cluster. This is particularly # useful when working with Pod Security Standards (PSS) or when you need # to meet specific security requirements. # apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-security-context spec: instances: 3 # Storage configuration storage: size: 1Gi # Custom PodSecurityContext # This will be applied to all pods in the cluster and merged with operator defaults. # Only RunAsUser, RunAsGroup, and SeccompProfile are merged from defaults if not specified. podSecurityContext: runAsUser: 26 runAsGroup: 26 fsGroup: 26 runAsNonRoot: true supplementalGroups: [1000, 2000] fsGroupChangePolicy: "OnRootMismatch" # Custom Container SecurityContext # This will be applied to all containers in the cluster pods and merged with operator defaults. # The operator provides secure defaults for all fields, which will be used if not explicitly set. securityContext: allowPrivilegeEscalation: false # Note: capabilities are not merged with operator defaults. # If specified, they fully replace any defaults. capabilities: drop: - ALL add: - NET_BIND_SERVICE privileged: false readOnlyRootFilesystem: true runAsNonRoot: true cluster-storage-class-with-backup.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: pg-backup spec: instances: 3 # Example of rolling update strategy: # - unsupervised: automated update of the primary once all # replicas have been upgraded (default) # - supervised: requires manual supervision to perform # the switchover of the primary primaryUpdateStrategy: unsupervised # Persistent storage configuration storage: storageClass: standard size: 1Gi # Backup properties backup: barmanObjectStore: destinationPath: s3://BUCKET_NAME/path/to/folder s3Credentials: accessKeyId: name: aws-creds key: ACCESS_KEY_ID secretAccessKey: name: aws-creds key: ACCESS_SECRET_KEY wal: compression: gzip backup-example.yaml ^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Backup metadata: name: pg-backup-example spec: cluster: name: pg-backup cluster-example-with-backup.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-with-backup spec: instances: 3 primaryUpdateStrategy: unsupervised # Persistent storage configuration storage: storageClass: csi-hostpath-sc size: 1Gi # Backup properties # This assumes a local minio setup backup: barmanObjectStore: destinationPath: s3://backups/ endpointURL: http://minio:9000 s3Credentials: accessKeyId: name: minio key: ACCESS_KEY_ID secretAccessKey: name: minio key: ACCESS_SECRET_KEY wal: compression: gzip data: additionalCommandArgs: - "--min-chunk-size=5MB" - "--read-timeout=60" - "-vv" cluster-example-with-backup-scaleway.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: pg-backup-scaleway spec: instances: 3 storage: storageClass: standard size: 1Gi backup: barmanObjectStore: destinationPath: "s3:///backups/" # change with your buckets name. endpointURL: "https://s3..scw.cloud" # change with your buckets location/region. s3Credentials: accessKeyId: name: scaleway key: ACCESS_KEY_ID secretAccessKey: name: scaleway key: ACCESS_SECRET_KEY region: name: scaleway key: ACCESS_REGION cluster-example-trigger-backup.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Backup metadata: name: cluster-example-trigger-backup spec: cluster: name: cluster-example-with-backup cluster-example-replica-from-backup-simple.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-replica-from-backup-simple spec: instances: 1 bootstrap: recovery: source: cluster-example-backup replica: enabled: true source: cluster-example-backup storage: size: 1Gi externalClusters: - name: cluster-example-backup barmanObjectStore: destinationPath: s3://backups/ endpointURL: http://minio:9000 s3Credentials: accessKeyId: name: minio key: ACCESS_KEY_ID secretAccessKey: name: minio key: ACCESS_SECRET_KEY cluster-example-with-volume-snapshot.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-with-volume-snapshot spec: instances: 3 primaryUpdateStrategy: unsupervised # Persistent storage configuration storage: storageClass: csi-hostpath-sc size: 1Gi walStorage: storageClass: csi-hostpath-sc size: 1Gi # Backup properties backup: volumeSnapshot: className: csi-hostpath-snapclass barmanObjectStore: destinationPath: s3://backups/ endpointURL: http://minio:9000 s3Credentials: accessKeyId: name: minio key: ACCESS_KEY_ID secretAccessKey: name: minio key: ACCESS_SECRET_KEY wal: compression: gzip backup-with-volume-snapshot.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Backup metadata: name: backup-with-volume-snapshot spec: method: volumeSnapshot cluster: name: cluster-example-with-volume-snapshot cluster-example-replica-from-volume-snapshot.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-replica-from-snapshot spec: instances: 1 storage: storageClass: csi-hostpath-sc size: 1Gi walStorage: storageClass: csi-hostpath-sc size: 1Gi bootstrap: recovery: source: cluster-example-with-volume-snapshot volumeSnapshots: storage: name: cluster-example-with-volume-snapshot-2-1692618163 kind: VolumeSnapshot apiGroup: snapshot.storage.k8s.io walStorage: name: cluster-example-with-volume-snapshot-2-wal-1692618163 kind: VolumeSnapshot apiGroup: snapshot.storage.k8s.io replica: enabled: true source: cluster-example-with-volume-snapshot externalClusters: - name: cluster-example-with-volume-snapshot connectionParameters: host: cluster-example-with-volume-snapshot-rw.default.svc user: postgres dbname: postgres password: name: cluster-example-with-volume-snapshot-superuser key: password barmanObjectStore: destinationPath: s3://backups/ endpointURL: http://minio:9000 s3Credentials: accessKeyId: name: minio key: ACCESS_KEY_ID secretAccessKey: name: minio key: ACCESS_SECRET_KEY wal: maxParallel: 8 cluster-example-replica-streaming.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-replica-example spec: instances: 1 bootstrap: pg_basebackup: source: cluster-example replica: enabled: true source: cluster-example storage: size: 1Gi # note the namespace default in the host name `cluster-example-rw.default.svc` # remember to change accordingly with the namespace of the main cluster externalClusters: - name: cluster-example connectionParameters: host: cluster-example-rw.default.svc user: streaming_replica sslmode: verify-full dbname: postgres # NOTE: if this cluster is created in a different namespace than the main cluster # remember to create the `-replication` and `-ca` secrets in the follower namespace # before creating the follower cluster sslKey: name: cluster-example-replication key: tls.key sslCert: name: cluster-example-replication key: tls.crt sslRootCert: name: cluster-example-ca key: ca.crt postgis-example.yaml ^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: postgis-example spec: imageName: ghcr.io/cloudnative-pg/postgresql:18.3-minimal-trixie instances: 1 storage: size: 1Gi postgresql: extensions: - name: postgis image: reference: ghcr.io/cloudnative-pg/postgis-extension:3.6.1-18-trixie ld_library_path: - system - -- apiVersion: postgresql.cnpg.io/v1 kind: Database metadata: name: postgis-example-app spec: name: app owner: app cluster: name: postgis-example extensions: - name: postgis version: 3.6.1 - name: postgis_raster - name: postgis_sfcgal - name: fuzzystrmatch - name: address_standardizer - name: address_standardizer_data_us - name: postgis_tiger_geocoder - name: postgis_topology cluster-example-with-roles.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-with-roles spec: instances: 3 storage: size: 1Gi managed: roles: - name: app createdb: true login: true - name: dante ensure: present comment: my database-side comment login: true superuser: false createdb: true createrole: false inherit: false replication: false bypassrls: false connectionLimit: 4 validUntil: "2053-04-12T15:04:05Z" inRoles: - pg_monitor - pg_signal_backend passwordSecret: name: cluster-example-dante - -- apiVersion: v1 data: username: ZGFudGU= password: ZGFudGU= kind: Secret metadata: name: cluster-example-dante type: kubernetes.io/basic-auth cluster-example-managed-services.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-managed-services spec: instances: 1 storage: size: 1Gi managed: services: ## disable the default services disabledDefaultServices: ["ro", "r"] additional: - selectorType: rw serviceTemplate: metadata: name: "test-rw" labels: test-label: "true" annotations: test-annotation: "true" spec: type: LoadBalancer cluster-example-with-tablespaces.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-with-tablespaces spec: instances: 3 storage: size: 1Gi tablespaces: - name: atablespace storage: size: 1Gi storageClass: standard temporary: true - name: another_tablespace storage: size: 2Gi storageClass: standard temporary: true - name: tablespacea1 storage: size: 2Gi storageClass: standard cluster-example-with-tablespaces-backup.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-with-tablespaces spec: instances: 3 storage: size: 1Gi backup: barmanObjectStore: destinationPath: s3://backups/ endpointURL: http://minio:9000 s3Credentials: accessKeyId: name: minio key: ACCESS_KEY_ID secretAccessKey: name: minio key: ACCESS_SECRET_KEY wal: compression: gzip tablespaces: - name: atablespace storage: size: 1Gi storageClass: standard - name: another_tablespace storage: size: 2Gi storageClass: standard - name: tablespacea1 storage: size: 2Gi storageClass: standard cluster-restore-with-tablespaces.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-restore-with-tablespaces spec: instances: 3 storage: size: 1Gi bootstrap: recovery: backup: name: cluster-example-with-tablespaces-20231128093940 tablespaces: atablespace: storage: size: 1Gi storageClass: standard another_tablespace: storage: size: 2Gi storageClass: standard tablespacea1: storage: size: 2Gi storageClass: standard pooler-external.yaml ^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Pooler metadata: name: pooler-example-rw spec: cluster: name: cluster-example instances: 3 type: rw serviceTemplate: metadata: labels: app: pooler spec: type: LoadBalancer pgbouncer: poolMode: session parameters: max_client_conn: "1000" default_pool_size: "10" cluster-example-logical-source.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example spec: instances: 3 imageName: ghcr.io/cloudnative-pg/postgresql:17 storage: size: 1Gi bootstrap: initdb: postInitApplicationSQL: - CREATE TABLE numbers (i SERIAL PRIMARY KEY, m INTEGER) - INSERT INTO numbers (m) (SELECT generate_series(1,10000)) - ALTER TABLE numbers OWNER TO app - CREATE TABLE numbers_two (i SERIAL PRIMARY KEY, m INTEGER) - INSERT INTO numbers_two (m) (SELECT generate_series(1,10000)) - ALTER TABLE numbers_two OWNER TO app - CREATE SCHEMA another_schema - ALTER SCHEMA another_schema OWNER TO app - CREATE TABLE another_schema.numbers_three (i SERIAL PRIMARY KEY, m INTEGER) - INSERT INTO another_schema.numbers_three (m) (SELECT generate_series(1,10000)) - ALTER TABLE another_schema.numbers_three OWNER TO app replicationSlots: highAvailability: synchronizeLogicalDecoding: true managed: roles: - name: app login: true replication: true postgresql: parameters: hot_standby_feedback: on sync_replication_slots: on - -- apiVersion: postgresql.cnpg.io/v1 kind: Publication metadata: name: cluster-example-pub spec: name: pub dbname: app cluster: name: cluster-example target: allTables: true cluster-example-logical-destination.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example-dest spec: instances: 1 storage: size: 1Gi bootstrap: initdb: import: type: microservice schemaOnly: true databases: - app source: externalCluster: cluster-example externalClusters: - name: cluster-example connectionParameters: host: cluster-example-rw.default.svc user: app dbname: app password: name: cluster-example-app key: password - -- apiVersion: postgresql.cnpg.io/v1 kind: Subscription metadata: name: cluster-example-dest-sub spec: cluster: name: cluster-example-dest name: sub dbname: app publicationName: pub externalClusterName: cluster-example parameters: failover: true publication-example.yaml ^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Publication metadata: name: publication-example spec: cluster: name: cluster-example name: pub-all dbname: app target: allTables: true publication-example-objects.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Publication metadata: name: publication-example-objects spec: cluster: name: cluster-example name: pub-objects dbname: app target: objects: - tablesInSchema: public - table: schema: another_schema name: numbers_three only: true subscription-example.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Subscription metadata: name: subscription-sample spec: name: sub dbname: app publicationName: pub-all cluster: name: cluster-example-dest externalClusterName: cluster-example database-example.yaml ^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml apiVersion: postgresql.cnpg.io/v1 kind: Database metadata: name: db-one spec: name: one owner: app cluster: name: cluster-example database-example-icu.yaml ^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: yaml # NOTE: this manifest will only work properly if the Postgres version supports # ICU locales and rules (version 16 and newer) apiVersion: postgresql.cnpg.io/v1 kind: Database metadata: name: db-icu spec: name: declarative-icu owner: app encoding: UTF8 localeProvider: icu icuLocale: en icuRules: fr template: template0 cluster: name: cluster-example