Skip to main content

Overview

PostgreSQL is a powerful open-source relational database. This template deploys a single-replica PostgreSQL instance with persistent storage and optional scheduled backups to AWS S3, GCS, or a self-hosted MinIO instance.
PostgreSQL on Control Plane operates as a single-replica deployment. Do not scale up the replica count, as this would result in multiple isolated instances rather than a replicated cluster. For a highly available setup, use the PostgreSQL Highly Available template instead.

What Gets Created

  • Stateful Postgres Workload — A single-replica PostgreSQL container with configurable resources.
  • Volume Set — Persistent storage for database data, with optional autoscaling.
  • Secret — A dictionary secret storing the database username and password, injected into the container at startup.
  • Identity & Policy — An identity bound to the workload with reveal access to the database credentials secret, and cloud storage access when backup is enabled.
  • PgBouncer Workload (optional) — A PgBouncer connection pooler deployed as a separate workload in front of PostgreSQL.
  • Backup Cron Workload (optional) — A scheduled pg_dump backup job that writes compressed SQL dumps to AWS S3, GCS, or MinIO.
This template does not create a GVC. You must deploy it into an existing GVC.

Installation

This template has no external prerequisites unless backup is enabled. To install, follow the instructions for your preferred method:

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

The default values.yaml for this template:

Credentials

  • config.username — PostgreSQL username. Change before deploying to production.
  • config.password — PostgreSQL password. Change before deploying to production.
  • config.database — Name of the database created on startup.
These values are only applied on first startup when the data directory is empty. Updating them after the initial deployment will have no effect on the running database. To change credentials or the database name on an existing instance, use PostgreSQL’s native commands (e.g. ALTER USER, ALTER DATABASE).

Resources

  • resources.minCpu / resources.minMemory — Minimum CPU and memory guaranteed to the workload.
  • resources.maxCpu / resources.maxMemory — Maximum CPU and memory the workload can use.

Storage

  • volumeset.capacity — Initial volume size in GiB (minimum 10).
  • volumeset.autoscaling.enabled — Automatically expand the volume as it fills. When enabled:
    • maxCapacity — Maximum volume size in GiB.
    • minFreePercentage — Trigger a scale-up when free space drops below this percentage.
    • scalingFactor — Multiply the current capacity by this factor when scaling up.

Internal Access

  • internalAccess.type — Controls which workloads can connect to PostgreSQL on port 5432:

Connecting to PostgreSQL

Once deployed, connect to the database from within the same GVC using:

PgBouncer Connection Pooling

PgBouncer is an optional connection pooler that sits in front of PostgreSQL and multiplexes application connections into a smaller pool of real database connections. This reduces connection overhead and protects PostgreSQL from exhaustion under high concurrency. When enabled, PgBouncer is deployed as a separate workload and becomes the primary connection endpoint for your applications:
  • pgbouncer.enabled — Enable or disable PgBouncer.
  • pgbouncer.poolMode — Controls how connections are reused:
  • pgbouncer.defaultPoolSize — Number of real PostgreSQL connections PgBouncer maintains per pool (default: 25).
  • pgbouncer.maxClientConn — Maximum number of client connections PgBouncer accepts (default: 1000).
  • pgbouncer.replicas — Number of PgBouncer instances. PgBouncer is stateless and can be scaled horizontally for high-throughput workloads.
  • pgbouncer.resources.cpu / pgbouncer.resources.memory — Resources allocated to each PgBouncer replica.
PgBouncer shares the same credentials and identity as the PostgreSQL workload — no additional secrets or IAM configuration is required. The userlist.txt and pgbouncer.ini are generated automatically from your config.username, config.password, and config.database values at startup.

Backup

Backup is disabled by default. When enabled, a cron workload runs pg_dump on the configured schedule and uploads compressed SQL dumps to AWS S3 or GCS.
Backup requires PostgreSQL 17 or later. Set backup.image to match your PostgreSQL version: ghcr.io/controlplane-com/backup-images/postgres-backup:18.1.0 for Postgres 18, or ghcr.io/controlplane-com/backup-images/postgres-backup:17.1.0 for Postgres 17.
  • backup.enabled — Enable scheduled backups.
  • backup.schedule — Cron expression for backup frequency (default: daily at 2am UTC).
  • backup.provideraws, gcp, or minio.
  • backup.resources.cpu / backup.resources.memory — Resources for the backup cron container.

Backup Prerequisites

AWS S3

Before enabling backup with provider: aws, complete the following in your AWS account:
  1. Create an S3 bucket. Set backup.aws.bucket to its name and backup.aws.region to its region.
  2. If you do not have a Cloud Account set up, refer to the docs to Create a Cloud Account. Set backup.aws.cloudAccountName to its name.
  3. Create an IAM policy with the following JSON, replacing YOUR_BUCKET_NAME:
  1. Set backup.aws.policyName to the name of the policy created in step 3.
  2. Set backup.aws.prefix to the folder path where backups will be stored.

GCS

Before enabling backup with provider: gcp, complete the following in your GCP account:
  1. Create a GCS bucket. Set backup.gcp.bucket to its name.
  2. If you do not have a Cloud Account set up, refer to the docs to Create a Cloud Account. Set backup.gcp.cloudAccountName to its name.
  3. Add the Storage Admin role to the GCP service account associated with the Cloud Account.
  4. Set backup.gcp.prefix to the folder path where backups will be stored.

MinIO

Before enabling backup with provider: minio, ensure your MinIO instance is accessible:
  1. Create a bucket in MinIO. Set backup.minio.bucket to its name.
  2. Set backup.minio.endpoint to the MinIO S3 API address including the port. For the minio marketplace template deployed in the same GVC, use http://WORKLOAD_NAME:9000.
  3. Set backup.minio.accessKey and backup.minio.secretKey to the MinIO root credentials — these match the admin.username and admin.password values from the MinIO template installation.
  4. Set backup.minio.prefix to the folder path where backups will be stored.
MinIO backup requires no Control Plane Cloud Account — credentials are passed directly to the backup job.

Restoring a Backup

Run the following from a client with access to the backup bucket: AWS S3:
GCS:
MinIO:

External References

PostgreSQL Documentation

Official PostgreSQL documentation

PgBouncer Documentation

PgBouncer configuration reference

Backup Image Source

Source code for the PostgreSQL backup container image

PostgreSQL Template

View the source files, default values, and chart definition