Skip to content
Back to Deployment

Deploying PostgreSQL

Self-hosted Postgres with Docker, tuning, backups, and high availability.

PlatformsAdvanced

Why

Self-hosting Postgres gives full control over config, extensions, and tuning. With Docker + pgBackRest + repmgr, you get HA, PITR, and extension support not always in managed offerings.

Platform-as-a-Service adoption grew 24% in 2024 as teams shift from VM management to git-push deploys. the cloud infrastructure market reached $330B in 2024, growing 22% year-over-year (Synergy Research), and PaaS layers capture the majority of new workloads.

When

Use self-hosted Postgres for custom extensions, cost optimization at scale, and compliance. Prefer managed (RDS, Supabase) for simplicity.

How

1. Docker — postgres:16 image with volume for data 2. Config — postgresql.conf tuning (shared_buffers, work_mem) 3. Init — init.sql in docker-entrypoint-initdb.d 4. Backup — pg_dump or pgBackRest for incremental 5. HA — repmgr or Patroni for replication + failover 6. Monitoring — pg_stat_statements, pg_stat_activity 7. Extensions — CREATE EXTENSION for pgvector, postgis

Example

# docker-compose.yml services: postgres: image: postgres:16 environment: POSTGRES_DB: mydb POSTGRES_PASSWORD: secret volumes: - pgdata:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql command: > postgres -c shared_buffers=256MB -c work_mem=16MB -c max_connections=200 volumes: pgdata: # Backup docker exec mydb pg_dump -U postgres mydb | gzip > backup.sql.gz # Restore gunzip < backup.sql.gz | docker exec -i mydb psql -U postgres mydb

Common Problems

  • ⚠shared_buffers too low — default 128MB, set to 25% of RAM for production
  • ⚠No backups — pg_dump is not enough, use pgBackRest for PITR
  • ⚠Configuration drift between environments — use infrastructure-as-code (Terraform/Pulumi) to keep dev/staging/prod identical

Best Practices

  • ✓Set shared_buffers to 25% of RAM — biggest single performance win
  • ✓Use pgBackRest for backups — incremental, compressed, PITR
  • ✓Set up health checks and graceful shutdown — handle SIGTERM to drain in-flight requests before exit

FAQ