This runbook deploys the primary Citus Coordinator (coord1) for a four-node PostgreSQL/Citus cluster running over a private WireGuard network.
| Host | Role | WireGuard IP |
|---|---|---|
| coord1 | Primary Coordinator | 92.243.18.209 |
| coord2 | Coordinator Standby | 92.243.18.66 |
| worker1 | Citus Worker | 92.243.18.201 |
| worker2 | Citus Worker | 92.243.18.208 |
This guide assumes:
16/main)psql --version
sudo pg_lsclusters
Expected:
Ver Cluster Port Status
16 main 5432 online
sudo apt update
sudo apt install -y postgresql-16-citus-14.1
Verify:
dpkg -l | grep postgresql-16-citus
Check current preload libraries:
sudo -u postgres psql -Atc \
"SHOW shared_preload_libraries;"
If empty:
sudo pg_conftool 16 main set shared_preload_libraries citus
If another library already exists:
sudo pg_conftool 16 main set \
shared_preload_libraries 'citus,pg_stat_statements'
Restart PostgreSQL:
sudo systemctl restart postgresql
Verify:
sudo -u postgres psql -Atc \
"SHOW shared_preload_libraries;"
Expected:
citus
sudo -u postgres createdb citus_cluster
Install the extension:
sudo -u postgres psql -d citus_cluster \
-c "CREATE EXTENSION citus;"
Verify:
sudo -u postgres psql -d citus_cluster \
-c "SELECT citus_version();"
Configure PostgreSQL to listen on localhost and the WireGuard interface.
sudo pg_conftool 16 main set \
listen_addresses '127.0.0.1,92.243.18.209'
Restart PostgreSQL:
sudo systemctl restart postgresql
Verify:
sudo ss -lntp | grep 5432
Expected:
127.0.0.1:5432
92.243.18.209:5432
Append to /etc/hosts:
92.243.18.209 coord1
92.243.18.66 coord2
92.243.18.201 worker1
92.243.18.208 worker2
Verify:
getent hosts coord1
getent hosts worker1
getent hosts worker2
Locate the active file:
sudo -u postgres psql -Atc \
"SHOW hba_file;"
Back it up:
HBA=$(sudo -u postgres psql -Atc "SHOW hba_file")
sudo cp "$HBA" "$HBA.bak"
Append:
# ==================================================
# Citus Cluster
# ==================================================
# Coordinator standby
host all all 92.243.18.66/32 scram-sha-256
# Streaming replication
host replication replicator 92.243.18.66/32 scram-sha-256
# Worker connections
host all all 92.243.18.201/32 trust
host all all 92.243.18.208/32 trust
Reload PostgreSQL:
sudo systemctl reload postgresql
Validate:
sudo -u postgres psql -P pager=off -c "
SELECT
line_number,
address,
auth_method,
error
FROM pg_hba_file_rules
WHERE address::text LIKE '10.47.%'
OR error IS NOT NULL;"
The error column should be empty.
Generate a password:
openssl rand -base64 32
Create the replication role:
CREATE ROLE replicator
WITH LOGIN
REPLICATION
PASSWORD '<generated-password>';
Verify:
SELECT rolname,
rolcanlogin,
rolreplication
FROM pg_roles
WHERE rolname='replicator';
If UFW is enabled:
sudo ufw allow in from 92.243.18.66 to 92.243.18.209 port 5432 proto tcp
sudo ufw allow in from 92.243.18.201 to 92.243.18.209 port 5432 proto tcp
sudo ufw allow in from 92.243.18.208to 92.243.18.209 port 5432 proto tcp
Verify:
sudo ufw status numbered
SELECT citus_set_coordinator_host('coord1',5432);
Verify:
SELECT
nodeid,
nodename,
nodeport,
noderole,
isactive
FROM pg_dist_node;
echo "=== PostgreSQL ==="
sudo pg_lsclusters
echo
echo "=== Citus Package ==="
dpkg -l | grep postgresql-16-citus
echo
echo "=== Preload ==="
sudo -u postgres psql -Atc \
"SHOW shared_preload_libraries;"
echo
echo "=== Citus Version ==="
sudo -u postgres psql -d citus_cluster \
-c "SELECT citus_version();"
echo
echo "=== PostgreSQL Listener ==="
sudo ss -lntp | grep 5432
echo
echo "=== HBA Validation ==="
sudo -u postgres psql -Atc "
SELECT count(*)
FROM pg_hba_file_rules
WHERE error IS NOT NULL;"
echo
echo "=== Coordinator Metadata ==="
sudo -u postgres psql -d citus_cluster -c "
SELECT nodeid,
nodename,
nodeport,
noderole,
isactive
FROM pg_dist_node;"
Expected results:
shared_preload_libraries = cituscitus_cluster database existscitus extension installed127.0.0.1:543210.47.0.1:5432pg_hba.conf validation returns 0 errorspg_dist_nodeAfter coord1 is fully validated:
SELECT * FROM citus_add_node('worker1',5432);
SELECT * FROM citus_add_node('worker2',5432);
coord2 as a PostgreSQL streaming replication standby.