Create a PostgreSQL service

Apply the following object on your namespace, as specified by its YAML description.

Minimal example

The following is the minimum configuration required to create a PostgreSQL instance. All other fields use the default values shown in the full example below.

Minimal PostgreSQL instance
apiVersion: vshn.appcat.vshn.io/v1
kind: VSHNPostgreSQL
metadata:
  name: pgsql-app1-prod (1)
  namespace: prod-app (2)
spec:
  parameters:
    size:
      plan: standard-2 (3)
  writeConnectionSecretToRef:
    name: postgres-creds (4)
1 Instance name
2 The namespace where the object will be created
3 Size plan for the instance. See Plans and Sizing for available options.
4 Secret where the connection details are provisioned. This secret must not exist before creation.
All omitted fields use their default values. See the full example below for a reference of all configurable options and their defaults.

Full example with defaults

The following example shows all commonly-configured fields with their default values. Copy, paste, and adjust the fields relevant to your use case.

PostgreSQL instance with all default values
apiVersion: vshn.appcat.vshn.io/v1
kind: VSHNPostgreSQL
metadata:
  name: pgsql-app1-prod (1)
  namespace: prod-app (2)
spec:
  parameters:
    service:
      majorVersion: "15" (3)
      serviceLevel: besteffort (4)
      tls:
        enabled: true (5)
      vacuumEnabled: false (6)
      repackEnabled: true (7)
    instances: 1 (8)
    updateStrategy:
      type: Immediate (9)
    size:
      plan: standard-2 (10)
    backup:
      enabled: true (11)
      schedule: "0 22 * * *" (12)
      retention: 6 (13)
      deletionProtection: true (14)
      deletionRetention: 7 (15)
    network:
      ipFilter:
        - 0.0.0.0/0 (16)
      serviceType: ClusterIP (17)
    security:
      deletionProtection: true (18)
    maintenance:
      dayOfWeek: tuesday (19)
      timeOfDay: "22:30:00" (20)
    encryption:
      enabled: false (21)
  writeConnectionSecretToRef:
    name: postgres-creds (22)
1 Instance name
2 The namespace where the object will be created
3 PostgreSQL major version. Default: "15". Supported versions: "12", "13", "14", "15", "16", "17", "18". See product docs for supported and end-of-life versions. On CloudNativePG, in-place major version upgrades are supported (no downgrades) — see major upgrade. On StackGres, version changes are not supported on existing instances.
4 Service level. besteffort (default) or guaranteed. See SLA for details.
5 Enable TLS for all connections. Default: true. On CloudNativePG, TLS is always enabled regardless of this setting. On StackGres (deprecated), this field controls SSL at the cluster level.
6 Run VACUUM during the maintenance window. Default: false. Only runs when instances > 0.
7 Run pg_repack during the maintenance window to reclaim bloat without locking. Default: true. Only runs when instances > 0.
8 Number of PostgreSQL instances in the cluster. Default: 1. Allowed values: 03. Setting this to 2 or 3 enables high-availability with read replicas. See Replicas for details.
9 When spec changes are applied. Default: Immediate (changes applied at once, may cause a brief downtime). Use OnRestart to defer changes until the next maintenance window. See Update Strategy for details.
10 Resource plan. See Plans and Sizing for available plans and custom sizing options.
11 Enable automatic backups. Default: true. When set to false, no backup bucket or WAL archiving is configured.
12 Backup schedule in cron format. If omitted, a random schedule is generated and stored in .status.schedules.backup.
13 Number of daily backups to keep. Default: 6.
14 Protect backups from deletion when the instance is deleted. Default: true. See Deletion Protection.
15 Number of days to retain backups after the instance is deleted. Default: 7.
16 List of allowed IPv4 CIDR ranges. When omitted, all traffic is allowed (equivalent to 0.0.0.0/0). Restrict this to your application’s IP range in production environments.
17 How the service is exposed. Default: ClusterIP (cluster-internal only). Use LoadBalancer for a dedicated public IPv4 address or TCPGateway for Gateway API access (CloudNativePG only).
18 Prevent accidental deletion of the claim. Default: true. See Deletion Protection.
19 Day of the week for the maintenance window. Allowed values: monday, tuesday, wednesday, thursday, friday, saturday, sunday. If omitted, a random day is generated and stored in .status.schedules.maintenance.
20 Time of day for the maintenance window in UTC, format hh:mm:ss. If omitted, a random time is generated and stored in .status.schedules.maintenance.
21 Enable encrypted storage for the instance. Default: false. See Encrypted PVC for details.
22 Secret where the connection details are provisioned. This secret must not exist before creation.
For up-to-date documentation of all available fields, see the API Reference. This page is generated directly from the API definition.

Changes to the claim spec take effect immediately on apply and bypass the maintenance window entirely.

Some changes (such as plan upgrades, replica count changes, resource sizing, or pinImageTag updates) can trigger pod restarts or short connection interruptions. Apply disruptive edits at a time that suits your workload.

StackGres (Deprecated)

VSHN PostgreSQL with StackGres is End of Life as of 31.08.2026. All new PostgreSQL instances use CloudNativePG by default. If you still have StackGres instances, follow the migration guide to move to CloudNativePG.

StackGres-specific features (not available in CNPG) are:

  • pgBouncer connection pooling

  • Envoy sidecar proxy for advanced monitoring

  • Dedicated Patroni resource allocation

To deploy your instance using StackGres, set spec.compositionRef.name:

apiVersion: vshn.appcat.vshn.io/v1
kind: VSHNPostgreSQL
metadata:
  name: pgsql-app1-prod
  namespace: prod-app
spec:
  compositionRef:
    name: vshnpostgres.vshn.appcat.vshn.io
  parameters:
    service:
      majorVersion: "16"
      pgBouncerSettings:
        pgbouncer:
          admin_users: postgres
    size:
      plan: standard-2
  writeConnectionSecretToRef:
    name: postgres-creds
Once set, the method of deployment cannot be changed afterwards. Similarly, existing instances cannot be switched to a different deployment method without migrating to a new instance.

Envoy Sidecar Proxy

By default, Envoy sidecar proxy is disabled on StackGres-based PostgreSQL instances. You can enable it by setting spec.parameters.service.enableEnvoy to true.

When enabled, Envoy provides an additional proxy layer that can be used for advanced monitoring and observability purposes.

apiVersion: vshn.appcat.vshn.io/v1
kind: VSHNPostgreSQL
metadata:
  name: pgsql-app1-prod
  namespace: prod-app
spec:
  compositionRef:
    name: vshnpostgres.vshn.appcat.vshn.io
  parameters:
    service:
      majorVersion: "16"
      enableEnvoy: true (1)
    size:
      plan: standard-2
  writeConnectionSecretToRef:
    name: postgres-creds
1 Enable Envoy sidecar proxy for advanced monitoring capabilities.

For more information about Envoy in StackGres, see the StackGres Envoy documentation.

Inspect your new PostgreSQL service

$  kubectl get vshnpostgresqls.vshn.appcat.vshn.io
NAME              SYNCED   READY   CONNECTION-SECRET   AGE
pgsql-app1-prod   True     True    postgres-creds      6m14s

When you see True in the READY column, it means the instance is provisioned and ready to use.

Find the connection details

The connection details are stored in a secret. You can retrieve them with the following command:

$ oc get secrets postgres-creds -o yaml

The output of the command above is a secret specification with the following structure:

apiVersion: v1
kind: Secret
metadata:
  name: postgres-creds
stringData:
  POSTGRESQL_DB: postgres (1)
  POSTGRESQL_HOST: my-postgres-example.my-cloud.com (2)
  POSTGRESQL_PASSWORD: my-secret (3)
  POSTGRESQL_PORT: 21699 (4)
  POSTGRESQL_URL: postgres://postgres:my-secret@my-postgres-example.my-cloud.com:21699/postgresql?sslmode=require (5)
  POSTGRESQL_USER: postgres (6)
  ca.crt: base64encoded(data) (7)
  tls.crt: base64encoded(data) (8)
  tls.key: base64encoded(data) (9)
1 Database name
2 Host to connect to
3 Password
4 Port
5 URL containing all necessary information to connect to the instance
6 Username
7 ca.crt to use when using sslmode=verify-full
8 tls.crt to use when connecting to instance
9 tls.key to use when connecting to instance
Not all fields apply to all providers