
Discover the best practices for securing SSH connections on Linux servers. Learn essential security tips like disabling root login, using SSH keys, and more for
Learn PostgreSQL containerization best practices—including secure images, persistent volumes, resource tuning, backups, monitoring & seamless upgrades—for reliable cloud-native deployments.
Containerizing PostgreSQL has revolutionized how developers, DevOps engineers, and sysadmins deploy and manage relational databases. With Docker and Kubernetes driving cloud-native infrastructure, following best practices in PostgreSQL containerization ensures scalability, maintainability, and reliability. As an SEO-savvy guide, this article targets developers seeking to streamline PostgreSQL setup, deployment, and operation in containers.
|
|
|
|
|
Choose a minimal, up-to-date, and supported base image:
Image | Pros | Cons |
---|---|---|
postgres:latest | Official, robust, auto-updated | May introduce sudden changes |
postgres:15-alpine | Lightweight, small size | Alpine musl may cause issues |
bitnami/postgresql:15 | Secure by default, configurable, K8s-ready | Slightly larger image size |
timescale/timescaledb:latest | Great for time-series workloads | Heavier, not necessary if not using Timescale |
💡Tip: Always specify a minor version tag (e.g., |
📄 |
FROM postgres:15.4-alpine
ENV POSTGRES_USER=myapp POSTGRES_PASSWORD=secretdb POSTGRES_DB=myappdb
COPY init-schema.sql /docker-entrypoint-initdb.d/
Contain environment variables in files using Docker Compose or Kubernetes Secrets.
services:
postgres:
image: postgres:15.4
env_file:
- ./secrets/postgres.env
📄 |
POSTGRES_USER=myapp
POSTGRES_PASSWORD=supersecret
POSTGRES_DB=myappdb
In Kubernetes use:
apiVersion: v1
kind: Secret
metadata:
name: pg-credentials
type: Opaque
data:
POSTGRES_USER: bXlhcHA= # base64 encoded
POSTGRES_PASSWORD: c3VwZXJzZWNyZXQ=
Avoid baking credentials into images or source code.
Use named Docker volumes or persistent volumes (PV) in Kubernetes to persist data beyond container lifetime.
Example in Docker Compose:
services:
postgres:
volumes:
- pg_data:/var/lib/postgresql/data
volumes:
pg_data:
In Kubernetes:
volumeClaimTemplates:
- metadata:
name: pg-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
Ensure the storage class supports fast I/O and snapshotting.
Set CPU and memory to avoid resource contention.
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "4Gi"
cpu: "2"
Scenario | Request | Limit |
---|---|---|
Small Dev Service | 500 m CPU / 1 GiB RAM | 1 CPU / 2 GiB RAM |
Medium Production DB | 1 CPU / 2 GiB | 4 CPU / 8 GiB |
Large Clustered Database | 2 + CPUs / 4 + GiB | 8 – 16 CPUs / 32 – 64 GiB |
⚠️ Avoid overcommit: PostgreSQL may crash on out-of-memory events. |
Set up cron jobs in sidecar containers or use Kubernetes CronJobs for regular backups.
CronJob YAML:
kind: CronJob
apiVersion: batch/v1
metadata:
name: pg-backup
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: postgres:15
envFrom:
- secretRef:
name: pg-credentials
command:
- sh
- "-c"
- |
pg_dump -U $POSTGRES_USER $POSTGRES_DB \
| gzip > /backups/backup-$(date +%F).sql.gz
volumeMounts:
- name: backups
mountPath: /backups
restartPolicy: OnFailure
volumes:
- name: backups
persistentVolumeClaim:
claimName: backup-pvc
Point-in-time recovery (PITR): enable WAL archiving.
ALTER SYSTEM SET wal_level = replica;
ALTER SYSTEM SET archive_mode = on;
ALTER SYSTEM SET archive_command = 'test ! -f /wal_archive/%f && cp %p /wal_archive/%f';
SELECT pg_reload_conf();
Regularly test restoration to ensure it works!
Health probes help orchestrators know when the DB is ready:
livenessProbe:
exec:
command:
- pg_isready
- "-U"
- "postgres"
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- pg_isready
- "-U"
- "postgres"
initialDelaySeconds: 5
periodSeconds: 5
Use Prometheus + Postgres Exporter to monitor metrics (connections, cache hit ratio, WAL lag). And set up alerts—e.g., replicated lag > 5s.
Practice rolling upgrades without downtime using replicas.
Workflow in Kubernetes:
|
|
|
Alternative using Logical Replication:
livenessProbe:
exec:
command:
- pg_isready
- "-U"
- "postgres"
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- pg_isready
- "-U"
- "postgres"
initialDelaySeconds: 5
periodSeconds: 5
Allow replication to catch up, then switch over.
Feature | Purpose | Example |
---|---|---|
StatefulSet + PVC | Stable network identity & storage | pg-0 , pg-1 pods |
Service (ClusterIP) | Stable client endpoint | postgres-service |
PodAntiAffinity | Spread replicas across nodes | requiredDuringScheduling |
StatefulSet UpdateStrategy | Rolling update on app changes | RollingUpdate |
Sidecar (Backup/Logging) | Decouple tasks like backup | pg_dump container |
|
|
|
|
|
# Run a dev container with a mounted volume
docker run -d \
--name pg_dev \
-e POSTGRES_PASSWORD=devpass \
-v pg_dev_data:/var/lib/postgresql/data \
postgres:15.4
# Check container health
docker exec pg_dev pg_isready -U postgres
# Backup from running container
docker exec pg_dev pg_dumpall -U postgres \
| gzip > pg_backup_$(date +%F).sql.gz
# Restore from backup
zcat pg_backup_2025-06-23.sql.gz \
| docker exec -i pg_dev psql -U postgres
# Kubernetes: check pod readiness
kubectl get pods -l app=postgres -o wide
# Stream WAL archiving
kubectl exec pg-0 -- tail -f /wal_archive
Containerization of PostgreSQL succeeds at scale when following the right patterns:
|
|
|
|
|
|
By embracing these containerization best practices, teams can build reliable, observable, and scalable PostgreSQL infrastructures fit for modern cloud-native environments. Did you find this article helpful? Your feedback is invaluable to us! Feel free to share this post with those who may benefit, and let us know your thoughts in the comments section below.
Discover the best practices for securing SSH connections on Linux servers. Learn essential security tips like disabling root login, using SSH keys, and more for
In this blog post, we’ll explore 12 best practices to help you organize your Ansible playbooks for optimal performance and maintainability. Table of Contents Introduction
Learn 10 best practices for Bash scripting and start writing scripts that are efficient and maintainable. This guide covers meaningful variable names, error handling, quoting