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;"