Skip to content

Deploy StackGres

Use the stackgres-operator and stackgres-cluster packages to run PostgreSQL under the StackGres operator.

This guide creates one PostgreSQL 16 instance with a 5 GiB volume. The target cluster must provide a default StorageClass, or the database instance must name one explicitly.

Install one operator instance in its own namespace:

how-to/package-stacks/stackgres-cluster.nix (L17–L19)
instances.stackgres-system.stackgres-operator = {
package = packages.stackgres-operator;
};

View source on GitHub ↗

The operator installs and reconciles the StackGres custom resource types. One operator can manage database clusters in other namespaces.

Add the database instance in the namespace where it should run:

how-to/package-stacks/stackgres-cluster.nix (L23–L34)
instances.database.postgres = {
package = packages.stackgres-cluster;
config = {
instances = 1;
postgres.version = "16";
storage.size = "5Gi";
instanceProfile = {
cpu = "500m";
memory = "1Gi";
};
};
};

View source on GitHub ↗

The stackgresCluster package resolves the operator through its stackgresOperator dependency. Kix also connects it to the StorageClass provided by the cluster flavor.

For a production cluster, set instances to match the number of PostgreSQL members you need, increase storage.size, and size instanceProfile for the workload. Set storage.storageClass when the flavor’s default is not suitable.

Evaluate the cluster before deploying it:

Run in kix-examples/
❱ kix check how-to-package-stackgres
 TOOL         RESULT  DETAILS                                                       
 eval         pass    34 manifests evaluated                                        
 kubeconform  pass    skipped (this validation tool is not yet integrated with Kix) 
 pluto        pass    skipped (this validation tool is not yet integrated with Kix) 
 kyverno      pass    skipped (this validation tool is not yet integrated with Kix) 
 scorecard    pass    0 errors, 3 warnings, 3 info

Inspect the custom resources that configure PostgreSQL:

Run in kix-examples/ Output excerpt
❱ kix build how-to-package-stackgres --output json
[
  {
    "apiVersion": "stackgres.io/v1",
    "kind": "SGCluster",
    "metadata": {
      "name": "postgres",
      "namespace": "database"
    },
    "spec": {
      "instances": 1,
      "postgres": {
        "flavor": "vanilla",
        "ssl": {
          "enabled": true
        },
        "version": "16"
      },
      "sgInstanceProfile": "postgres-profile",
      "configurations": {
        "sgPostgresConfig": "postgres-pg16-config"
      },
      "persistentVolume": {
        "size": "5Gi",
        "storageClass": "standard"
      }
    }
  },
  {
    "apiVersion": "stackgres.io/v1",
    "kind": "SGInstanceProfile",
    "metadata": {
      "name": "postgres-profile",
      "namespace": "database"
    },
    "spec": {
      "cpu": "500m",
      "memory": "1Gi"
    }
  }
]

The SGCluster refers to the generated instance profile and PostgreSQL configuration by name. StackGres uses those resources to create and operate the StatefulSet, Services, and persistent volume claims.

Deploy the operator and database, then check their status:

Run in kix-examples/
❱ kix deploy how-to-package-stackgres
❱ kix status how-to-package-stackgres
❱ kubectl get sgcluster -n database postgres

The StackGres operator creates a Service and a Secret named postgres in the database namespace. Forward the primary Service port:

❱ kubectl port-forward -n database service/postgres 5432:5432

In another terminal, read the generated superuser password and connect:

❱ export PGPASSWORD=$(kubectl get secret -n database postgres -o jsonpath='{.data.superuser-password}' | base64 --decode)
❱ psql --host 127.0.0.1 --username postgres --dbname postgres

Stop the port-forward with Ctrl-C. Clear the shell variable when you finish:

❱ unset PGPASSWORD

If the SGCluster does not become ready, inspect it with kubectl describe, then check the StackGres operator logs and PVC state in the database namespace.