Production-ready PostgreSQL deployment with support for standalone and streaming replication architectures, structured
access controls, TLS, External Secrets Operator, optional replication slots, and production hardening controls.
Key Features
Standalone and replication — Single instance or primary with streaming replicas
Automatic initialization — Init scripts, extensions, and custom configuration
S3 backup — Scheduled backups to S3-compatible storage via CronJob
Metrics — Prometheus exporter with ServiceMonitor
Security — Non-root containers, TLS support with private-key permission normalization, structured pg_hba.conf CIDRs, NetworkPolicy controls, and ServiceAccount token control
Replication slots — Optional physical slots with WAL retention limits for safer replica catch-up behavior
External Secrets Operator — Optional external-secrets.io/v1 resources for auth, TLS, and backup credentials
Persistent storage — Configurable PVCs with storage class selection
Architecture
Standalone
Single PostgreSQL instance with persistent storage and optional S3 backup.
Replication
Primary with streaming replicas, read-only service, and backup CronJob.
The chart does not install External Secrets Operator and does not create a SecretStore or ClusterSecretStore.
Enable this only when the operator and referenced store already exist.
Production Path
The default install remains intentionally suitable for local development and disposable test clusters. A production
deployment should explicitly set existing Secrets or External Secrets, storage, resources, config.allowedClientCIDRs,
config.allowedReplicationCIDRs, TLS, metrics, backup, and NetworkPolicy behavior.
Use the structured CIDR lists first. config.pgHbaEntries and raw config.pgHba remain escape hatches for advanced
cases, but production baselines should not depend on a full raw pg_hba.conf override.
Replication slots are disabled by default for compatibility. If replication.slots.enabled=true, also set WAL limits
such as replication.wal.maxSlotWalKeepSize so a stalled replica cannot retain unbounded WAL.
Operational Notes
The chart keeps internal health checks, metrics, and built-in backup on PostgreSQL’s standard postgres database.
If a reused PVC contains a valid data directory but is missing the default postgres database, the primary pod repairs that database during startup before normal readiness checks rely on it.
auth.database remains the application bootstrap database. It is created only on first initialization of a fresh data directory.
Set initdb.runDefaultScript=false when custom or externally managed init scripts should run without the chart-generated application and replication user bootstrap script.
docker-entrypoint-initdb.d scripts only run when the data directory is empty. Existing PVCs keep their current roles and databases during upgrades.
Dual-stack Networking
PostgreSQL Services accept Kubernetes dual-stack configuration. By default, both service.ipFamilyPolicy and service.ipFamilies are unset and the chart inherits whatever the cluster advertises (matching prior behavior). Setting them propagates to every chart-managed Service: client, primary, replicas, metrics, and the headless StatefulSet services.
PreferDualStack is the safer choice for clusters that may be single- or dual-stack: omit ipFamilies and the cluster auto-populates whatever it supports. Set ipFamilies explicitly only when the cluster is configured for both families — the Kubernetes API rejects an explicit family the cluster does not advertise. RequireDualStack enforces both.
Configuration Reference
This reference covers the complete values.yaml surface for the PostgreSQL chart.
Core
Parameter
Type
Default
Description
architecture
string
standalone
Deployment architecture: standalone or replication.
nameOverride
string
""
Override the chart name.
fullnameOverride
string
""
Override the full release name.
commonLabels
object
{}
Extra labels added to all rendered resources.
clusterDomain
string
cluster.local
Kubernetes cluster domain used in generated DNS names.
Image
Parameter
Type
Default
Description
image.repository
string
docker.io/library/postgres
PostgreSQL runtime image repository.
image.tag
string
"18.3-trixie"
PostgreSQL runtime image tag.
image.pullPolicy
string
IfNotPresent
Image pull policy for PostgreSQL containers.
imagePullSecrets
array
[]
Optional image pull secrets for private registries.
Authentication
Parameter
Type
Default
Description
auth.postgresPassword
string
""
PostgreSQL superuser password when not using an existing secret.
auth.database
string
app
Application database created on first bootstrap.
auth.username
string
app
Application username created on first bootstrap.
auth.password
string
""
Application user password when not using an existing secret.
auth.replicationUsername
string
replicator
Replication username used by read replicas.
auth.replicationPassword
string
""
Replication password when not using an existing secret.
auth.existingSecret
string
""
Existing secret containing PostgreSQL passwords.
auth.existingSecretPostgresPasswordKey
string
postgres-password
Secret key holding the PostgreSQL superuser password.
auth.existingSecretUserPasswordKey
string
user-password
Secret key holding the application user password.
auth.existingSecretReplicationPasswordKey
string
replication-password
Secret key holding the replication user password.
PostgreSQL Configuration
Parameter
Type
Default
Description
config.localAuthMethod
string
scram-sha-256
Authentication method for local Unix-socket connections.
config.allowedClientCIDRs
array
["0.0.0.0/0", "::/0"]
CIDRs allowed to connect to regular PostgreSQL databases.
config.allowedReplicationCIDRs
array
["0.0.0.0/0", "::/0"]
CIDRs allowed to connect to the replication pseudo-database.
config.preset
string
none
Optional PostgreSQL tuning preset: none, small, medium, or large.
config.postgresql
string
""
Raw postgresql.conf content appended after generated settings.
config.pgHbaEntries
array
[]
Structured pg_hba.conf entries appended after generated defaults.
config.pgHba
string
""
Raw pg_hba.conf content appended after generated rules.
TLS
Parameter
Type
Default
Description
tls.enabled
boolean
false
Enable TLS for PostgreSQL and internal clients.
tls.existingSecret
string
""
Existing secret containing server TLS material.
tls.certFilename
string
tls.crt
Certificate filename inside the TLS secret.
tls.keyFilename
string
tls.key
Private key filename inside the TLS secret.
tls.caFilename
string
ca.crt
CA certificate filename inside the TLS secret.
tls.sslMode
string
require
libpq SSL mode used by internal probes, replication, and exporter.
tls.minProtocolVersion
string
TLSv1.2
Minimum accepted PostgreSQL TLS protocol version.
tls.volumePermissions.enabled
boolean
false
Copy TLS material to an owned emptyDir and restrict the private key to 0600.
Initialization
Parameter
Type
Default
Description
initdb.runDefaultScript
boolean
true
Run the chart-generated app database, app user, and replication user script.
initdb.scripts
object
{}
Additional scripts written into docker-entrypoint-initdb.d.
initdb.existingConfigMap
string
""
Existing ConfigMap mounted into docker-entrypoint-initdb.d.
Standalone
Parameter
Type
Default
Description
standalone.resourcesPreset
string
none
Optional resource preset for standalone mode.
standalone.persistence.enabled
boolean
true
Enable a PVC for standalone mode.
standalone.persistence.storageClass
string
""
StorageClass for the standalone PVC.
standalone.persistence.accessModes
array
["ReadWriteOnce"]
Access modes for the standalone PVC.
standalone.persistence.size
string
8Gi
PVC size for standalone mode.
standalone.resources
object
{}
Explicit resource requests and limits for standalone mode.
Replication - Primary
Parameter
Type
Default
Description
replication.primary.resourcesPreset
string
none
Optional resource preset for the primary pod.
replication.primary.persistence.enabled
boolean
true
Enable PVCs for the primary StatefulSet.
replication.primary.persistence.storageClass
string
""
StorageClass for primary PVCs.
replication.primary.persistence.accessModes
array
["ReadWriteOnce"]
Access modes for primary PVCs.
replication.primary.persistence.size
string
20Gi
PVC size for the primary pod.
replication.primary.resources
object
{}
Explicit resource requests and limits for the primary pod.
replication.primary.probes.requireWritable
boolean
true
In replication mode, require primary readiness to confirm the pod is not in recovery mode.
Replication - Read Replicas
Parameter
Type
Default
Description
replication.readReplicas.resourcesPreset
string
none
Optional resource preset for replica pods.
replication.readReplicas.replicaCount
integer
2
Number of asynchronous read replica pods.
replication.readReplicas.persistence.enabled
boolean
true
Enable PVCs for replica StatefulSets.
replication.readReplicas.persistence.storageClass
string
""
StorageClass for replica PVCs.
replication.readReplicas.persistence.accessModes
array
["ReadWriteOnce"]
Access modes for replica PVCs.
replication.readReplicas.persistence.size
string
20Gi
PVC size for each replica.
replication.readReplicas.resources
object
{}
Explicit resource requests and limits for replica pods.
for breaking changes in values structure. Always back up your data before upgrading.
When switching from standalone to replication, set auth.replicationPassword before upgrading
PVC resize requires the storage class to support volume expansion (allowVolumeExpansion: true)
Metrics sidecar changes may cause a pod restart during upgrade
Common Issues
Pod stuck in CrashLoopBackOff
Usually caused by incorrect auth.postgresPassword on upgrade. PostgreSQL does not re-initialize
auth when the data directory already exists. Check logs with kubectl logs <pod> and verify the
password matches the existing data.
Slow replication sync
For large databases, initial replica sync can take time. Increase readReplicas.resources and ensure the storage
class provides adequate IOPS. Monitor replication lag with the Prometheus exporter (pg_replication_lag metric).
Using with connection poolers
For high-connection workloads, deploy PgBouncer alongside PostgreSQL. Point your application to PgBouncer and
configure it to connect to the PostgreSQL service.