PgDog Helm Chart
April 29, 2026 · View on GitHub
Production-ready Helm chart for PgDog with high availability, security, and resource management features.
Features
✅ Resource limits with guaranteed QoS (1GB:1CPU ratio)
✅ PodDisruptionBudget for high availability
✅ Pod anti-affinity for spreading across nodes
✅ ExternalSecrets integration for secure credential management
✅ ServiceAccount and RBAC with minimal permissions
✅ Pinned image versions for production deployments
Quick Start
- Install Helm
- Configure
kubectlto point to your K8s cluster - Add our Helm repository:
helm repo add pgdogdev https://helm.pgdog.dev - Configure databases and users in
values.yaml - Install:
helm install <name> pgdogdev/pgdog -f values.yaml
All resources will be created in <name> namespace.
Configuration
Configuration is done via values.yaml. All PgDog settings from
pgdog.toml and users.toml are supported. General settings
([general] section) are top level. Use camelCase format instead
of snake_case, for example: checkout_timeout becomes
checkoutTimeout.
Basic Example
workers: 2
defaultPoolSize: 15
openMetricsPort: 9090
logFormat: json
logLevel: info
Docker Image
By default, the chart uses the appVersion from Chart.yaml as the image
tag. This ensures the chart deploys a known-compatible version of PgDog
without requiring explicit configuration.
To override with a specific version:
image:
repository: ghcr.io/pgdogdev/pgdog
tag: "v1.2.3" # Pin to specific version
pullPolicy: IfNotPresent
To pin to an exact build, use a digest instead of a tag:
image:
repository: ghcr.io/pgdogdev/pgdog
digest: "sha256:abc123def456..." # Immutable reference
pullPolicy: IfNotPresent
When digest is specified, it takes precedence over tag.
Legacy format (still supported for backward compatibility):
image:
name: ghcr.io/pgdogdev/pgdog:main
pullPolicy: Always
Databases & Users
Add databases to databases list:
databases:
- name: "prod"
host: "10.0.0.1"
Add users to users list:
users:
- name: "alice"
database: "prod"
password: "hunter2" # See ExternalSecrets for secure storage
⚠️ For production: Use ExternalSecrets instead of plain text passwords (see ExternalSecrets section below).
Mirroring
Add mirrors to mirrors list. For example:
mirrors:
- sourceDb: "prod"
destinationDb: "staging"
High Availability
PodDisruptionBudget
Ensures minimum pod availability during voluntary disruptions (enabled by default):
podDisruptionBudget:
enabled: true
minAvailable: 1 # At least 1 pod always available
Pod Anti-Affinity
Spreads pods across nodes for better reliability (enabled by default):
podAntiAffinity:
enabled: true
type: soft # "soft" (preferred) or "hard" (required)
Config Change Restarts
By default, ConfigMap changes are not automatically picked up by
running pods. Enable restartOnConfigChange to trigger a rolling
restart whenever the rendered config changes:
restartOnConfigChange: true
This injects a checksum/config pod annotation that changes when the
config template output changes, causing Kubernetes to roll the pods.
ExternalSecrets Integration
Securely manage credentials using ExternalSecrets operator:
Option 1: Create ExternalSecret with chart
externalSecrets:
enabled: true
create: true
secretStoreRef:
name: aws-secrets-manager
kind: SecretStore
remoteRefs:
- secretKey: users.toml
remoteRef:
key: pgdog/users
Option 2: Use existing ExternalSecret
externalSecrets:
enabled: true
create: false
secretName: "my-secret" # Name of Secret you created
ServiceAccount & RBAC
RBAC with minimal permissions is enabled by default:
serviceAccount:
create: true
annotations: {}
rbac:
create: true
Resource Management
Default resources use Guaranteed QoS with 1GB:1CPU ratio:
resources:
requests:
cpu: 1000m # 1 CPU
memory: 1Gi # 1GB
limits:
cpu: 1000m
memory: 1Gi
You can set noCpuLimits: true to omit CPU limits. This allows containers to use idle CPU on the host.
noCpuLimits: true
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
memory: 512Mi
Prometheus (optional)
Prometheus metrics can be collected with a sidecar. Enable by
configuring prometheusPort:
prometheusPort: 9091
# Resources for Prometheus sidecar
prometheusResources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 100Mi
Make sure it's different from openMetricsPort. You can configure
Prometheus in templates/prom/config.yaml.
Grafana Remote Write
To send metrics to Grafana Cloud or a Grafana instance, configure the remote write settings:
grafanaRemoteWrite:
url: "https://prometheus-prod-XX-XXX.grafana.net/api/prom/push"
basicAuth:
username: "123456" # Grafana Cloud user ID
password: "your-api-key" # Grafana Cloud API key
queueConfig:
capacity: 10000
maxShards: 50
minShards: 1
maxSamplesPerSend: 5000
batchSendDeadline: 5s
minBackoff: 30ms
maxBackoff: 5s
The queueConfig settings use Prometheus defaults and can be tuned
for performance. Remote write is automatically enabled when url is
set.
Plugins
Add plugins to the plugins list. Each plugin requires a name; config is
optional and accepts inline TOML content. When config is provided, a
<name>.toml file is added to the ConfigMap and mounted at
/etc/pgdog/<name>.toml.
plugins:
- name: pgdog_routing
config: |
[routing]
key = "value"
- name: pgdog_auth
TCP Keep-Alive Configuration
Configure socket-level TCP keep-alive behavior (optional):
tcpKeepalive: true
tcpTime: 7200000 # 2 hours (ms) before first keepalive probe
tcpInterval: 75000 # 75 seconds (ms) between keepalive probes
tcpRetries: 9 # Number of keepalive probes before connection is dropped
These settings control the TCP keep-alive behavior for database connections. All time values are in milliseconds. If not specified, system defaults are used.
Contributions
Contributions are welcome. Please open a pull request / issue with requested changes.
License
MIT