Skip to main content

Overview

PgDog is a PostgreSQL connection pooler, load balancer and query router written in Rust. It speaks the PostgreSQL wire protocol on port 6432, so applications change only their connection string: PgDog multiplexes many client connections onto a small pool of real backend connections, sends writes to a primary backend and spreads SELECT queries across replica backends. This template deploys the proxy only — it does not run PostgreSQL. Point it at an existing PostgreSQL or PostgreSQL Highly Available install, or at any external PostgreSQL endpoint. Every credential comes from a secret you create before installing, so no password passes through Helm values.
This template does not create a GVC. It deploys into a GVC you already have, and every resource lands in the GVC you install into. The PostgreSQL backend must already exist and be reachable from that GVC.

What Gets Created

How credentials reach PgDog. PgDog reads usernames and passwords only from its config files on disk, and a secret reference cannot be placed inside a file the chart writes. So the chart renders only the credential-free part of pgdog.toml; your secrets are injected into the container as environment variables, and the startup script writes the [admin] table and users.toml from them each time the container starts. The template creates no secret that contains a credential, and uninstalling never deletes yours.

Prerequisites

Both kinds of secret must exist before you install. Secrets are org-level, so no GVC flag is involved. A PostgreSQL backend must also be running, with the role and database your pooled users will connect as.
1

Create one credentials secret per pooled user

A dictionary secret holding exactly two keys, username and password. PgDog checks client logins against this pair and opens its backend connections with it, so it must be a real PostgreSQL role on the backend:
If your backend is a PostgreSQL install, you can skip this step and reuse the dictionary secret that template already reads — it holds the same username and password keys, and PgDog ignores its extra database key.Set users[0].credentialsSecretName to this name.
2

Create the admin password secret

An opaque secret with encoding plain, whose payload is the password for PgDog’s admin database. It is deliberately separate from the pooled-user secrets, so an application that can read its own credentials cannot also reach the admin database:
Use printf, not echo — echo adds a trailing newline, and the startup script refuses to start with a password that contains one.Set admin.passwordSecretName to this name.
3

Read a secret back when you need it

The -o yaml is required — a bare cpln secret reveal prints only a summary table:
Create the secrets before installing. The template refuses to render when a secret name is blank, but a name pointing at a secret that does not exist installs “successfully” and then wedges silently: every resource is reported created, the workload never becomes ready, and cpln logs returns zero lines because no container ever starts. The only place the missing secret is named is status.versions[].message:
It is get-deployments — plain cpln workload get has no versions key. Once the secret exists the workload recovers on its own after several minutes, or immediately if you force a redeployment:

Installation

Install with your backend, one pooled user and the admin secret. databases and users are lists, and setting one field of a list entry with --set replaces the whole list, so set every field of each entry:
DATABASE must be a real database on the backend, and users[0].database must match a databases[].name. With the PostgreSQL template, POSTGRES_WORKLOAD_NAME is that release’s RELEASE_NAME-postgres workload. To install using another method, follow the instructions for it:

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

Image and Resources

The PgDog image, the CPU and memory reservation (minCpu, minMemory) and limit (maxCpu, maxMemory), and the number of proxy replicas:
Each replica keeps its own connection pool — see Scaling and Availability before raising replicas.

Backend Databases

Each entry becomes a [[databases]] block in pgdog.toml. Entries that share a name form one cluster: PgDog sends writes to the primary entry and reads to the replica entries.
For a backend in the same GVC, always use the fully qualified host WORKLOAD_NAME.GVC_NAME.cpln.local — a bare workload name does not resolve for every workload type.

Pooled Users

Each entry becomes a [[users]] block in users.toml. The username and password come from the dictionary secret named by credentialsSecretName; only the routing target is a value:
To pool a second user, create a second dictionary secret (Prerequisites) and add a second entry — one secret per entry, since a secret holds one username and password pair:
The chart adds a reveal target to the policy for each secret automatically. Two entries may name the same secret, which routes one role to two databases.

Connection Pooling

Timeouts

All values are in milliseconds:

Load Balancing

How reads are spread across replica backends. With readWriteSplit: include_primary the primary also serves reads:

Admin Database

PgDog’s built-in admin database for pool statistics and introspection. The database and user names are values; the password comes from the opaque secret you created:

Authentication and Logging

Access

Internal access controls which workloads may reach the proxy. Public access opens a TCP load balancer on port 6432 to the internet:
With type: workload-list, list each allowed caller in workloads as //gvc/GVC_NAME/workload/WORKLOAD_NAME. A change to either access setting can take several minutes to take effect; re-test with a real PostgreSQL client before concluding it did not apply.

Connecting

Applications connect exactly as they would to PostgreSQL, on port 6432. The username and password are those in the pooled user’s credentials secret (cpln secret reveal SECRET_NAME -o yaml). To verify the proxy end to end from your machine — PgDog listening, your credentials accepted and a query answered by the backend — tunnel to it:
Then, from another terminal:
A row with the backend’s PostgreSQL version means the whole path works. Through the same tunnel, connect to the admin database as admin.user and run SHOW POOLS or SHOW CLIENTS to inspect the pools.

Operations

Rotating Credentials

PgDog builds its config files once, when the container starts, so changing a secret has no effect until the workload is redeployed. Because a pooled user’s pair is also PgDog’s backend login, change the role’s password in PostgreSQL first, then update the secret by applying it whole:
The admin password secret is opaque — apply it the same way with type: opaque and data holding encoding: plain and payload: NEW-VALUE. Then redeploy so PgDog picks up the new values:
Until the redeployment, PgDog keeps using the old values, with no error and the workload still reported ready.

Upgrading From 1.0.0

Version 1.0.0 took the pooled-user and admin passwords as Helm values, with working defaults published in the public template repository. Version 1.1.0 moves every credential into secrets you create and renames the resource limits:
Carrying old values forward stops the upgrade. These conditions are rejected at render time, so the upgrade fails before any resource is touched and the running release is left as it was:
To upgrade an existing install:
1

Create the secrets

Follow Prerequisites. Put the username and password your applications already use into the pooled-user secret so existing connection strings keep working, and choose a new admin password — the 1.0.0 default was published.
2

Update your values

Remove users[].name, users[].password and admin.password. Set users[].credentialsSecretName and admin.passwordSecretName, and rename resources.cpu and resources.memory to resources.maxCpu and resources.maxMemory if you had overridden them.
3

Run the upgrade

PgDog holds no data, so there is nothing to migrate; the proxy is replaced and clients reconnect. Pass your full values, including every field of each databases and users entry:

Scaling and Availability

PgDog is stateless and holds no data, so a restart or reschedule only drops open client connections; give applications a reconnect policy. The default is one replica, and every upgrade replaces it. To run more proxies, raise replicas. Each replica keeps its own pool, so the backend sees up to replicas × pooling.defaultPoolSize connections per pool — lower defaultPoolSize accordingly and keep the total under the backend’s max_connections. The template ships with a single replica; running several has not been verified.

Troubleshooting

Symptom: the install reports every resource created, the workload stays not ready, and cpln logs prints zero lines.Cause: a secret named by admin.passwordSecretName or a users[].credentialsSecretName does not exist, so the container never starts.Fix: read the deployment message — it is the only place the missing secret is named:
Look for The secret <name> no longer exists. Workload updates are paused until the secret is added or the reference to the secret removed. under status.versions[].message. Create that secret (Prerequisites); the workload recovers on its own after several minutes, or force a redeployment to skip the wait.
Symptom: the workload restarts repeatedly and cpln logs shows a line beginning FATAL:.Cause: a secret exists but a value in it is unusable. FATAL: ... is missing or empty names the secret and key that is empty or absent (a credentials secret needs both username and password). FATAL: ... contains a newline means the value has a trailing newline, usually from creating it with echo.Fix: recreate or re-apply the named secret with the right keys, using printf '%s' rather than echo for an opaque value (Rotating Credentials), then force a redeployment.
Symptom: a client fails with could not translate host name "RELEASE_NAME-pgdog" to address.Cause: the bare workload name does not resolve for PgDog’s workload type.Fix: use the fully qualified host RELEASE_NAME-pgdog.GVC_NAME.cpln.local. Apply the same rule to every databases[].host that points at a workload in the GVC.
Symptom: a client reaches port 6432 but authentication fails, or PgDog cannot open backend connections.Cause: PgDog uses the pooled user’s username and password for the backend connection too, so the pair must be a real role on the backend with access to the target database. A password changed in PostgreSQL but not in the secret — or changed in the secret without a redeployment — produces the same failure.Fix: compare cpln secret reveal SECRET_NAME -o yaml with the role on the backend, make them match, then force a redeployment.
Symptom: cpln helm install or cpln helm upgrade exits before touching any resource with a message such as users[0].database is "...", which is not a name in .Values.databases or At least one entry is required in .Values.databases.Cause: a users[].database does not match any databases[].name, or a list was replaced by a partial --set (setting one field of a list entry drops the others), or a 1.0.0 key is still set (Upgrading From 1.0.0).Fix: pass every field of each databases and users entry, make each users[].database match a databases[].name, and remove the old keys.

Important Notes

  • Create every pooled-user credentials secret and the admin password secret before you install; a missing one wedges the workload with no log output.
  • PgDog is a proxy only — the PostgreSQL backend, its roles and its databases must already exist.
  • Clients connect on port 6432, not 5432, using the fully qualified RELEASE_NAME-pgdog.GVC_NAME.cpln.local.
  • Each pooled user’s credentials are also PgDog’s backend login, so they must match a real PostgreSQL role.
  • A changed secret takes effect only after cpln workload force-redeployment.
  • In transaction mode, session state (SET variables, temporary tables, advisory locks) is not kept between transactions; use session if your application depends on it.
  • On 1.0.0, treat the published default passwords as compromised and choose new ones when you upgrade.

External References

PgDog Documentation

Official PgDog documentation

pgdog.toml Reference

Pool, timeout, load-balancing and database settings

users.toml Reference

How PgDog maps pooled users onto backend databases

PgDog GitHub

Source code and issue tracker

PgDog Template

View the source files, default values, and chart definition