1version: '3.8'
2
3# PostgreSQL Primary-Standby Replication Setup
4# This Docker Compose file creates a PostgreSQL streaming replication cluster
5# with one primary and one standby instance.
6
7services:
8 # Primary PostgreSQL Instance
9 postgres-primary:
10 image: postgres:16-alpine
11 container_name: postgres-primary
12 hostname: postgres-primary
13 environment:
14 # Basic PostgreSQL configuration
15 POSTGRES_USER: postgres
16 POSTGRES_PASSWORD: postgres_pass
17 POSTGRES_DB: production
18
19 # Replication user credentials
20 POSTGRES_REPLICATION_USER: replicator
21 POSTGRES_REPLICATION_PASSWORD: repl_password
22
23 volumes:
24 # Data persistence
25 - primary-data:/var/lib/postgresql/data
26
27 # Shared WAL archive directory
28 - wal-archive:/var/lib/postgresql/wal_archive
29
30 # Custom initialization script
31 - ./init-primary.sh:/docker-entrypoint-initdb.d/init-primary.sh:ro
32
33 ports:
34 - "5432:5432"
35
36 networks:
37 - postgres-cluster
38
39 command:
40 - postgres
41 # Enable WAL archiving for PITR (Point-In-Time Recovery)
42 - -c
43 - wal_level=replica
44 - -c
45 - max_wal_senders=10
46 - -c
47 - max_replication_slots=10
48 - -c
49 - hot_standby=on
50 - -c
51 - archive_mode=on
52 - -c
53 - archive_command=test ! -f /var/lib/postgresql/wal_archive/%f && cp %p /var/lib/postgresql/wal_archive/%f
54 - -c
55 - archive_timeout=60
56
57 healthcheck:
58 test: ["CMD-SHELL", "pg_isready -U postgres"]
59 interval: 10s
60 timeout: 5s
61 retries: 5
62
63 # Standby PostgreSQL Instance (Replica)
64 postgres-standby:
65 image: postgres:16-alpine
66 container_name: postgres-standby
67 hostname: postgres-standby
68 environment:
69 POSTGRES_USER: postgres
70 POSTGRES_PASSWORD: postgres_pass
71
72 # Replication connection settings
73 PRIMARY_HOST: postgres-primary
74 PRIMARY_PORT: 5432
75 REPLICATION_USER: replicator
76 REPLICATION_PASSWORD: repl_password
77
78 volumes:
79 # Separate data volume for standby
80 - standby-data:/var/lib/postgresql/data
81
82 # Shared WAL archive (read-only access)
83 - wal-archive:/var/lib/postgresql/wal_archive:ro
84
85 # Initialization script for standby setup
86 - ./init-standby.sh:/docker-entrypoint-initdb.d/init-standby.sh:ro
87
88 ports:
89 - "5433:5432"
90
91 networks:
92 - postgres-cluster
93
94 depends_on:
95 postgres-primary:
96 condition: service_healthy
97
98 command:
99 - postgres
100 - -c
101 - hot_standby=on
102 - -c
103 - max_standby_streaming_delay=30s
104 - -c
105 - wal_receiver_status_interval=10s
106
107 healthcheck:
108 test: ["CMD-SHELL", "pg_isready -U postgres"]
109 interval: 10s
110 timeout: 5s
111 retries: 5
112
113# Named volumes for data persistence
114volumes:
115 primary-data:
116 driver: local
117 standby-data:
118 driver: local
119 wal-archive:
120 driver: local
121
122# Network for cluster communication
123networks:
124 postgres-cluster:
125 driver: bridge