q下面是跨主机用 Docker Compose 部署 PostgreSQL + PostGIS 主从复制的完整详细步骤(主库 + 从库),主从都用官方 PostGIS 镜像 postgis/postgis:15-3.3
,并注意网络与持久化。复制即可。
🚩 跨主机 PostgreSQL + PostGIS 主从复制完整部署方案
基本假设
主机 | 角色 | IP | 端口映射 |
---|---|---|---|
主机A | 主库 | 192.168.10.101 | 5432 → 5432 |
主机B | 从库 | 192.168.10.102 | 5433 → 5432 |
1. 主机A(主库)部署步骤
1.1 创建目录
mkdir -p ~/pg-master/{data,config}
cd ~/pg-master
1.2 准备配置文件
config/postgresql.conf
listen_addresses = '*'
port = 5432
wal_level = replica
max_wal_senders = 10
wal_keep_size = 64
hot_standby = on
config/pg_hba.conf
# 允许所有 IP 用 md5 连接(可根据安全需求收紧)
host all all 0.0.0.0/0 md5
host replication postgres 0.0.0.0/0 md5
1.3 创建 docker-compose.yml
version: "3.8"services:postgis-master:image: postgis/postgis:15-3.3container_name: postgis-masterrestart: alwaysenvironment:POSTGRES_DB: gisPOSTGRES_USER: postgresPOSTGRES_PASSWORD: masterpassports:- "5432:5432"volumes:- ./data:/var/lib/postgresql/data- ./config/postgresql.conf:/etc/postgresql/postgresql.conf- ./config/pg_hba.conf:/etc/postgresql/pg_hba.confcommand: >postgres -c config_file=/etc/postgresql/postgresql.confnetworks:- pgnetnetworks:pgnet:driver: bridge
1.4 启动主库容器
docker-compose up -d
1.5 初始化数据库,创建 PostGIS 扩展及授权复制权限
docker exec -it postgis-master psql -U postgres -d gis
在 psql 里执行:
CREATE EXTENSION postgis;
ALTER ROLE postgres WITH REPLICATION;
2. 主机B(从库)部署步骤
2.1 创建目录
mkdir -p ~/pg-slave/data
cd ~/pg-slave
2.2 创建 docker-compose.yml
version: "3.8"services:postgis-slave:image: postgis/postgis:15-3.3container_name: postgis-slaverestart: alwaysenvironment:POSTGRES_USER: postgresPOSTGRES_PASSWORD: masterpassports:- "5433:5432"volumes:- ./data:/var/lib/postgresql/datanetworks:- pgnetcommand: >bash -c "if [ ! -s /var/lib/postgresql/data/PG_VERSION ]; thenpg_basebackup -h 192.168.10.101 -p 5432 -U postgres -D /var/lib/postgresql/data -Fp -Xs -P -Rfi &&postgres"networks:pgnet:driver: bridge
其中下面这段:
这一步骤的作用:
-
pg_basebackup
:首次启动从库时,自动从主库拉取数据目录快照(全量数据),包括数据库数据文件和 WAL 日志配置。 -
-R
参数:会自动在从库数据目录写入**standby.signal
**文件(PostgreSQL 12+ 的新机制,取代旧的 recovery.conf),并且自动生成主库连接的复制配置(primary_conninfo
),这就是主从连接的配置。-
primary_conninfo
里包括主库 IP、端口、用户名、密码等信息,从库根据它连接主库,接收 WAL 日志持续同步。
-
command: >bash -c "if [ ! -s /var/lib/postgresql/data/PG_VERSION ]; thenpg_basebackup -h 192.168.10.101 -p 5432 -U postgres -D /var/lib/postgresql/data -Fp -Xs -P -Rfi &&postgres"
2.3 启动从库容器
docker-compose up -d
3. 测试验证
3.1 主库插入测试数据
docker exec -it postgis-master psql -U postgres -d gis
执行:
CREATE TABLE test(id SERIAL PRIMARY KEY, name TEXT);
INSERT INTO test(name) VALUES ('hello from master');
3.2 从库查看同步数据
docker exec -it postgis-slave psql -U postgres -d gis
执行:
SELECT * FROM test;
-- 应该能看到 'hello from master'
4. 注意事项总结
-
确保主机之间 5432 端口(主库)开放,防火墙允许通信
-
pg_hba.conf
允许从库主机 IP 访问复制权限 -
主从镜像都用
postgis/postgis:15-3.3
,保证插件文件一致 -
从库首次启动自动通过
pg_basebackup
拉取主库数据,后续通过 WAL 复制同步 -
持久化目录映射保证数据不会丢失
-
网络配置建议使用内网桥接网络或 Docker Swarm overlay 网络
5. 额外推荐命令
查看主库日志:
docker logs -f postgis-master
查看从库日志:
docker logs -f postgis-slave
查看当前数据库扩展:
SELECT * FROM pg_available_extensions WHERE name='postgis';
📋 复制即用版本(笔记版)
# 主机A 主库目录准备
mkdir -p ~/pg-master/{data,config} && cd ~/pg-master# postgresql.conf
cat > config/postgresql.conf <<EOF
listen_addresses = '*'
port = 5432
wal_level = replica
max_wal_senders = 10
wal_keep_size = 64
hot_standby = on
EOF# pg_hba.conf
cat > config/pg_hba.conf <<EOF
host all all 0.0.0.0/0 md5
host replication postgres 0.0.0.0/0 md5
EOF# docker-compose.yml
cat > docker-compose.yml <<EOF
version: "3.8"
services:postgis-master:image: postgis/postgis:15-3.3container_name: postgis-masterrestart: alwaysenvironment:POSTGRES_DB: gisPOSTGRES_USER: postgresPOSTGRES_PASSWORD: masterpassports:- "5432:5432"volumes:- ./data:/var/lib/postgresql/data- ./config/postgresql.conf:/etc/postgresql/postgresql.conf- ./config/pg_hba.conf:/etc/postgresql/pg_hba.confcommand: >postgres -c config_file=/etc/postgresql/postgresql.confnetworks:- pgnet
networks:pgnet:driver: bridge
EOFdocker-compose up -ddocker exec -it postgis-master psql -U postgres -d gis -c "CREATE EXTENSION postgis;"
docker exec -it postgis-master psql -U postgres -c "ALTER ROLE postgres WITH REPLICATION;"# 主机B 从库目录准备
mkdir -p ~/pg-slave/data && cd ~/pg-slave# docker-compose.yml
cat > docker-compose.yml <<EOF
version: "3.8"
services:postgis-slave:image: postgis/postgis:15-3.3container_name: postgis-slaverestart: alwaysenvironment:POSTGRES_USER: postgresPOSTGRES_PASSWORD: masterpassports:- "5433:5432"volumes:- ./data:/var/lib/postgresql/datanetworks:- pgnetcommand: >bash -c "if [ ! -s /var/lib/postgresql/data/PG_VERSION ]; thenpg_basebackup -h 192.168.10.101 -p 5432 -U postgres -D /var/lib/postgresql/data -Fp -Xs -P -Rfi &&postgres"
networks:pgnet:driver: bridge
EOFdocker-compose up -d# 测试主库插入数据:
docker exec -it postgis-master psql -U postgres -d gis -c "CREATE TABLE test(id SERIAL PRIMARY KEY, name TEXT);"
docker exec -it postgis-master psql -U postgres -d gis -c "INSERT INTO test(name) VALUES ('hello from master');"# 测试从库查询数据:
docker exec -it postgis-slave psql -U postgres -d gis -c "SELECT * FROM test;"