CN

Running PostgreSQL in Docker: A Complete Guide for Developers

Learn how to run PostgreSQL 16 in Docker, understand configuration options, and set up a production-ready container. Includes volume management, networking, and security best practices.

PostgreSQL 16 is here, and running it in Docker makes life much easier. No more compatibility issues between different machines or operating systems. Let's dive into setting it up properly.

Understanding PostgreSQL Versions

PostgreSQL 16 (released September 2023) brings significant improvements:

  • Better performance for parallel queries
  • Improved logical replication
  • Enhanced monitoring capabilities

When choosing a version tag for Docker:

  • postgres:16 - Latest PostgreSQL 16.x
  • postgres:16.1 - Specific version
  • postgres:16-alpine - Smaller image size, Alpine-based

Basic Docker Compose Setup

Here's a basic setup to get PostgreSQL running:

docker-compose.yml
version: '3.8'
services:
  postgres:
    image: postgres:16
    container_name: my_postgres
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: your_password
      POSTGRES_DB: mydb
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U admin -d mydb"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  postgres_data:

Let's break down each part:

Environment Variables

PostgreSQL container recognizes several environment variables:

Environment Variables Configuration
environment:
  POSTGRES_USER: admin          # Database superuser
  POSTGRES_PASSWORD: password   # Superuser password
  POSTGRES_DB: mydb            # Default database
  # Optional variables
  POSTGRES_INITDB_ARGS: "--data-checksums"
  POSTGRES_HOST_AUTH_METHOD: "scram-sha-256"

Volume Management

Data persistence is crucial. There are two approaches:

  1. Named volumes (recommended):
Named Volumes Configuration
volumes:
  - postgres_data:/var/lib/postgresql/data
  1. Bind mounts (for development):
Bind Mounts Configuration
volumes:
  - ./data:/var/lib/postgresql/data

Named volumes are preferred because Docker manages them, ensuring proper permissions.

Container Health Checks

Health checks verify database availability:

Health Check Configuration
healthcheck:
  test: ["CMD-SHELL", "pg_isready -U admin -d mydb"]
  interval: 10s    # How often to check
  timeout: 5s      # When to consider check failed
  retries: 5       # How many retries before unhealthy

Running Multiple PostgreSQL Versions

Sometimes you need different versions running simultaneously:

Multiple PostgreSQL Versions Setup
services:
  postgres16:
    image: postgres:16
    ports:
      - "5432:5432"
    # ... other config

  postgres15:
    image: postgres:15
    ports:
      - "5433:5432"
    # ... other config

Custom Configuration

Override PostgreSQL settings using a custom config file:

  1. Create postgresql.conf:
postgresql.conf
max_connections = 100
shared_buffers = 128MB
effective_cache_size = 512MB
maintenance_work_mem = 128MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
work_mem = 8MB
min_wal_size = 1GB
max_wal_size = 4GB
  1. Mount it in docker-compose:
Custom Configuration Mount
services:
  postgres:
    volumes:
      - ./postgresql.conf:/etc/postgresql/postgresql.conf
    command: postgres -c 'config_file=/etc/postgresql/postgresql.conf'

Connecting to Your Container

From another container:

Container Connection Configuration
services:
  app:
    environment:
      DATABASE_URL: "postgresql://admin:password@postgres:5432/mydb"

From your machine:

Local Connection Command
psql -h localhost -p 5432 -U admin -d mydb

Backup and Restore

Create backup script backup.sh:

backup.sh
#!/bin/bash
docker exec my_postgres pg_dump -U admin mydb > backup.sql

Restore script restore.sh:

restore.sh
#!/bin/bash
docker exec -i my_postgres psql -U admin mydb < backup.sql

Advanced Topics

SSL Support

Enable SSL by mounting certificates:

SSL Configuration
services:
  postgres:
    volumes:
      - ./server.key:/var/lib/postgresql/server.key
      - ./server.crt:/var/lib/postgresql/server.crt
    command: -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key

Replication Setup

For primary-replica setup:

Replication Configuration
services:
  primary:
    environment:
      POSTGRES_REPLICA_MODE: primary
      
  replica:
    environment:
      POSTGRES_REPLICA_MODE: replica
      POSTGRES_MASTER_HOST: primary

Ready to start using PostgreSQL with Docker? Run:

Start Command
docker-compose up -d

Remember to replace default passwords in production environments and follow security best practices.

Want to read more articles like that?

Sign up to get notified when I publish more.

No spam. One click unsubscribe.

Read More on Fado Code Camp