Standalone HA Deployment with DC-DR (4 Machines)
Extend 3-machine standalone HA with a DR node at a separate site and protect ServiceOps against a full DC failure with a manual switchover to the DR site.
This layout extends the 3-machine standalone HA setup with a single DR machine that acts as a Patroni replica at a separate site. Use it when you need geographic redundancy for disaster recovery alongside local high availability on the DC side.
Prerequisites
Before starting, confirm the following:
- Operating System: Ubuntu and RHEL
- PostgreSQL Version: 16 or 17
- 4 machines provisioned and reachable over the network
- ServiceOps installed on DC Master, DC Slave, and DR Machine (follow the Standalone Installation Guide)
- Back up your database before starting any HA configuration step if you are working on an existing production environment. See the ServiceOps Application and Database Backup Procedure.
- Root or sudo access on all 4 machines
- A common OS user with sudo access on all nodes
- Setup scripts extracted on their respective machines:
MotadataETCDSetupU24on the DC Observer and DR machineMotadataPatroniSetupU24on DC Master, DC Slave, and DR machineMotadataAppHASetupon the DC ObserverMotadataHAFileSyncon DC Master, DC Slave, and DR machineMotadata_DCDR_Setup.shon DC Master, DC Slave, and DR machine
- Firewall ports open on each machine:
| Machine | Open Ports |
|---|---|
| DC Observer / HAProxy / ETCD | 80 (Optional), 443, 2379, 2380, 5000, 7000 |
| DC Master (APP + DB) | 80 (Optional), 443, 5432, 8008 |
| DC Slave (APP + DB) | 80 (Optional), 443, 5432, 8008 |
| DR Machine (APP + DB + ETCD) | 80 (Optional), 443, 5432, 8008 2379, 2380, 5000, 7000 |
- Back up your database before starting any configuration step on an existing production environment. See the ServiceOps Application and Database Backup Procedure.
- Back up your HAProxy configuration on the Observer machine from
/etc/haproxybefore making any changes.
Architecture Overview

The DC-DR layout spans two sites. The DC site runs a full 3-machine standalone HA setup. The DR site runs a single machine that handles both observer functions and the ServiceOps application with database.
| Site | Role | Machine | Example IP |
|---|---|---|---|
| DC | Observer / HAProxy / ETCD / HA Observer | DC Observer | 172.16.13.163 |
| DC | APP + DB Node 1 (Master) | DC Master | 172.16.13.153 |
| DC | APP + DB Node 2 (Slave) | DC Slave | 172.16.13.159 |
| DR | ETCD + APP + DB (Node 3) | DR Machine | 172.16.13.169 |
Components and Roles
- DC Observer (HA Proxy / ETCD / HA Observer): Single entry point for all Agents, Technicians, and Requesters on the DC side. HAProxy load-balances application traffic on ports
80and443and routes database connections to the Patroni Leader through port5000and7000. ETCD on ports2379and2380stores cluster state and coordinates Patroni leader election across all nodes, including the DR site. The HA Observer monitors both DC servers and triggers failover scripts when the Master becomes unreachable. - DC Master Server (APP + DB): Active server handling all live application requests on the DC side. ServiceOps and the Patroni Leader database run on the same machine as Node 1. Ports
5432and8008handle database and Patroni health checks. File DB Sync keeps non-database files in sync with the DC Slave. - DC Slave Server (APP + DB): Passive standby server on the DC side, kept in continuous sync with the DC Master through Data Replication and File DB Sync. Patroni automatically promotes it to Leader when the DC Master fails. This is Node 2 in the Patroni cluster. Ports
5432and8008handle database and Patroni traffic. - DR Master Server (ETCD + APP + DB): Single disaster recovery machine at a separate site. Runs ETCD for local cluster participation, ServiceOps, and the Patroni Replica database as Node 3. DB Sync and File DB Sync connections from the DC Slave keep the DR machine current. The DR node carries
nofailover: trueso Patroni does not promote it automatically during DC-side failover. Traffic switches to the DR site only when you run the switchover script manually. - Patroni: Manages PostgreSQL replication from the DC Master across the DC Slave and the DR machine. DC-side failover promotes the DC Slave automatically. DR promotion requires a manual switchover script.
- File DB Sync: Synchronizes non-database files between DC Master and DC Slave bidirectionally, and from the DC side to the DR machine, keeping attachments, patches, packages, and logs consistent across all nodes.
Part 1: DC Side Configuration
Configure the DC Observer, DC Master, and DC Slave in this order before configuring the DR machine.
Step 1: Download Setup Files
Download the zip file containing all setup files from the Download Links page and extract it on all four machines before proceeding.
Step 2: Set Up the DC Observer (ETCD and HAProxy)
Run the following steps on the DC Observer machine (172.16.13.163).
Give
MotadataETCDSetupU24execute permissions and run it:chmod 777 MotadataETCDSetupU24
./MotadataETCDSetupU24
Type
yeswhen prompted to install and configure ETCD.
Enter
1when prompted for the ETCD node number.Single ETCD Node for DC SideThe DC side uses a single ETCD node. Leave all additional ETCD node IP prompts blank and press Enter to skip them.

Leave all additional ETCD node prompts blank and press Enter.

Type
yeswhen prompted to install and configure HAProxy.
Enter the DB and APP IP addresses when prompted:
Prompt Value DB Node 1 IP 172.16.13.153(DC Master)DB Node 2 IP 172.16.13.159(DC Slave)APP Node 1 IP 172.16.13.153(DC Master)APP Node 2 IP 172.16.13.159(DC Slave)
ETCD and HAProxy setup on the DC Observer is complete.
Verify the HAProxy Configuration
Open /etc/haproxy/haproxy.cfg and confirm it matches this structure:
global
maxconn 100
defaults
log global
mode tcp
retries 2
timeout client 30m
timeout connect 4s
timeout server 30m
timeout check 5s
listen stats
mode http
bind *:7000
stats enable
stats uri /
listen postgres
bind *:5000
option httpchk
http-check expect status 200
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server etcd1 172.16.13.153:5432 maxconn 100 check port 8008
server etcd2 172.16.13.159:5432 maxconn 100 check port 8008
listen backend
bind *:80
balance roundrobin
mode tcp
option tcp-check
server ubuntu1 172.16.13.153:80 check port 80
server ubuntu2 172.16.13.159:80 check port 80
Verify ETCD Service Status
Check that the ETCD service is running before continuing:
systemctl status motadata_etcd

If the service is inactive, start it:
systemctl start motadata_etcd
Step 3: Configure the DC Master Database
Run the following steps on DC Master (172.16.13.153).
Give
MotadataPatroniSetupU24execute permissions and run it:chmod 777 MotadataPatroniSetupU24
./MotadataPatroniSetupU24
Enter
1when asked for the node number. This machine is Node 1 (Master).Enter the DC Slave IP address when prompted for Node 2:
172.16.13.159.
Enter the DR machine IP address when prompted for Node 3:
172.16.13.169.

Enter the DC Observer ETCD IP address when prompted:
172.16.13.163.
Patroni setup on the DC Master is complete.

After setup, confirm the Patroni service is inactive on the DC Master. If it shows active, stop it:
systemctl status patroni
systemctl stop patroni
Step 4: Configure the DC Slave Database
Run the following steps on DC Slave (172.16.13.159).
Give
MotadataPatroniSetupU24execute permissions and run it:chmod 777 MotadataPatroniSetupU24
./MotadataPatroniSetupU24Enter
2when asked for the node number. This machine is Node 2 (Slave).
Enter the DC Master IP address when prompted for Node 1:
172.16.13.153.Enter the DR machine IP address when prompted for Node 3:
172.16.13.169.

Enter the DC Observer ETCD IP address when prompted:
172.16.13.163.
After setup, confirm the Patroni service on the DC Slave is inactive. If it shows active, stop it:
systemctl status patroni
systemctl stop patroni
Do not continue to Step 5 until the DC Slave Patroni service is inactive.

Step 5: Configure the DC Master Application
Run the following steps on DC Master (172.16.13.153).
- Copy
MotadataPatroniHAMasterSlaveAppConfigfrom/opt/HAto the home directory. - Give it execute permissions and run it:
chmod 777 MotadataPatroniHAMasterSlaveAppConfig
./MotadataPatroniHAMasterSlaveAppConfig

- Enter the DC Observer IP address when prompted:
172.16.13.163.

- Enter
masterwhen asked for the machine role.


DC Master application configuration is complete.
Step 6: Configure the DC Slave Application
Run the following steps on DC Slave (172.16.13.159).
- Copy
MotadataPatroniHAMasterSlaveAppConfigfrom the DC Master/opt/HAfolder to the DC Slave. - Give it execute permissions and run it:
chmod 777 MotadataPatroniHAMasterSlaveAppConfig
./MotadataPatroniHAMasterSlaveAppConfig - Enter the DC Observer IP address when prompted:
172.16.13.163. - Enter
slavewhen asked for the machine role.

- Enter the DC Master application DB password when prompted.
- Retrieve the DB password from the DC Master configuration file located at the path,
cat /opt/flotomate/main-server/lib/boot-hosted-exec.conf. - The password must be identical on all machines.

DC Slave application configuration is complete.

Step 7: Configure File Sync on the DC Master
Run the following steps on DC Master (172.16.13.153).
- Change to the
/opt/HAdirectory and runMotadataHAFileSync:cd /opt/HA
./MotadataHAFileSync

- Enter the DC Slave IP address when prompted for Server 1:
172.16.13.159.

- Enter the DR machine IP address when prompted for Server 2:
172.16.13.169.
- Enter the common SSH username when prompted. Enter username that is available on all nodes and used for ssh between nodes.

File sync configuration on the DC Master is complete.

Step 8: Configure File Sync on the DC Slave
Run the following steps on DC Slave (172.16.13.159).
Change to the
/opt/HAdirectory and runMotadataHAFileSync:cd /opt/HA
./MotadataHAFileSyncEnter the DC Master IP address when prompted for Server 1:
172.16.13.153.Enter the DR machine IP address when prompted for Server 2:
172.16.13.169.Enter the common SSH username when prompted. This username should be available on all nodes and used for ssh between nodes.
File sync configuration on the DC Slave is complete.
Step 9: Run DB Configuration on the DC Master
Run the following steps on DC Master (172.16.13.153).
- Copy
MotadataPatroniHADBConfigfrom/opt/HAto the home directory, give it execute permissions, and run it:chmod 777 MotadataPatroniHADBConfig
./MotadataPatroniHADBConfig


- Enter
ywhen asked to reload and restart Patroni members. Perform this twice. Press Enter if prompted for a version.



DC Master DB configuration is complete.
Step 10: Run DB Configuration on the DC Slave
Run the following steps on DC Slave (172.16.13.159).
- Run
MotadataPatroniHADBConfig:chmod 777 MotadataPatroniHADBConfig
./MotadataPatroniHADBConfig

- Enter
ywhen asked to reload and restart Patroni members. Perform this twice. Press Enter if prompted for a version.

DC Slave DB configuration is complete.

If an old HA configuration already exists, remove it after taking a backup:
rm -rf /opt/HA
Step 11: Configure the Application HA Observer
Run the following steps on the DC Observer machine (172.16.13.163).
Run this script as a normal user. Do not use root or sudo. The script fails when run as root.
- Give
MotadataAppHASetupexecute permissions and run it:chmod 777 MotadataAppHASetup
./MotadataAppHASetup

- Enter the SSH username when prompted. Use the username that exists on all machines.
- Enter
22for the SSH port.

- Enter the DC Master IP address and password when prompted.

- Enter the DC Slave IP address and sudo password when prompted.

- Press Enter at the key-pair generation prompts. Enter
Yif prompted to overwrite an existing key pair.

Application HA Observer configuration is complete. DC side configuration is now done. Proceed to Part 2 for DR side configuration.

Part 2: DR Side Configuration
Configure the DR machine only after completing all 11 steps of Part 1. The DR machine runs ETCD, ServiceOps, and the Patroni database as Node 3 with no HAProxy.
Step 1: Set Up the DR Observer (ETCD Only)
Run the following steps on the DR machine (172.16.13.169).
- Give
MotadataETCDSetupU24execute permissions and run it:chmod 777 MotadataETCDSetupU24
./MotadataETCDSetupU24

Type
yeswhen prompted to install and configure ETCD.Enter
1when prompted for the ETCD node number.

- Leave all additional ETCD node IP prompts blank and press Enter. The DR side does not maintain ETCD clustering, so no additional node IPs are required.

- Enter
nowhen prompted to install and configure HAProxy. The DR machine is a single-node setup and does not require HAProxy.

ETCD setup on the DR machine is complete.
Step 2: Configure the DR Database with Patroni
Run the following steps on the DR machine (172.16.13.169).
- Give
MotadataPatroniSetupU24execute permissions and run it:chmod 777 MotadataPatroniSetupU24
./MotadataPatroniSetupU24

- Enter
3when asked for the node number. The DR machine is Node 3 in the Patroni cluster.

- Enter the DC Master IP address when prompted for Node 1:
172.16.13.153. Enter the DC Slave IP address when prompted for Node 2:172.16.13.159.

Press Enter when prompted for the PostgreSQL port to accept the default.
Enter the DC Observer ETCD IP address when prompted:
172.16.13.163.Use the DC Side ETCD IP on the DR MachineThe DR machine connects to the DC side ETCD for cluster coordination. The DR side is down by default and stays in contact with DC side coordination. Enter the DC Observer IP here, not the DR machine's own IP.

Patroni setup on the DR machine is complete.
Step 3: Configure the DR Application
Run the following steps on the DR machine (172.16.13.169).
Copy
MotadataPatroniHAMasterSlaveAppConfigfrom/opt/HAto the home directory.Give it execute permissions and run it:
chmod 777 MotadataPatroniHAMasterSlaveAppConfig
./MotadataPatroniHAMasterSlaveAppConfigEnter the DR machine's own IP address when prompted for the Observer IP:
172.16.13.169.DR Observer IP Is the DR Machine ItselfOn the DR side, enter the DR machine's own IP as the Observer IP. Do not enter the DC Observer IP here.

- Enter
slavewhen asked for the machine role.

- Enter the DC Master application DB password when prompted.

Retrieve the DB password from the DC Master before running this step:
cat /opt/flotomate/main-server/lib/boot-hosted-exec.conf
DR application configuration is complete.
Step 4: Configure File Sync on the DR Machine
Run the following steps on the DR machine (172.16.13.169).
Change to the
/opt/HAdirectory and runMotadataFileSync:cd /opt/HA
./MotadataFileSyncEnter the DC Master IP address when prompted for Server 1:
172.16.13.153.


- Enter the DC Slave IP address when prompted for Server 2:
172.16.13.159.

- Enter the common SSH username when prompted.

File sync configuration on the DR machine is complete.

Step 5: Run DB Configuration on the DR Machine
Run the following steps on the DR machine (172.16.13.169).
Change to the
/opt/HAdirectory and runMotadataPatroniHADBConfig:cd /opt/HA
chmod 777 MotadataPatroniHADBConfig
./MotadataPatroniHADBConfigPress Enter when prompted for the PostgreSQL port to accept the default.

- Enter
ywhenever asked to reload and restart Patroni members.

- Verify that three database nodes appear in the cluster output after configuration completes. The DR node shows
nofailover: true.
DC-DR setup is complete. Proceed to Part 3 to configure passwordless SSH communication between all nodes.
Part 3: Configure Passwordless SSH Between All Nodes
This step sets up SSH key-based authentication between the DC Master, DC Slave, and DR machine so that switchover scripts can execute across nodes without password prompts.
Copy Motadata_DCDR_Setup.sh from /opt/HA to the home directory of the normal user before running it. Run the script as a normal user, not root.
Step 1: Run on the DC Master
Run the following steps on DC Master (172.16.13.153).
- Copy
Motadata_DCDR_Setup.shto the home directory and run it as a normal user:cp /opt/HA/Motadata_DCDR_Setup.sh ~/
cd ~
./Motadata_DCDR_Setup.sh

- Enter the common SSH username when prompted.
- Enter
22for the SSH port.

- Enter the DC Master's own IP address when prompted for the current server IP.

Enter the password when prompted. The script generates an SSH key pair.
Enter the DC Slave IP address when prompted for Server 1:
172.16.13.159.Enter the DR IP address when prompted for Server 2:
172.16.13.169.
- Enter the DC Slave password when prompted. Enter it again if prompted a second time.

Passwordless SSH setup on the DC Master is complete.
Step 2: Run on the DC Slave
Run the following steps on DC Slave (172.16.13.159).
- Copy
Motadata_DCDR_Setup.shto the home directory and run it as a normal user:cp /opt/HA/Motadata_DCDR_Setup.sh ~/
cd ~
./Motadata_DCDR_Setup.sh

- Enter the same SSH username and port
22. - Enter the DC Slave's own IP address as the current server IP and enter the password.
- Enter the DC Master IP address when prompted for Server 1:
172.16.13.153. - Enter the DR IP address when prompted for Server 2:
172.16.13.169 - Enter the DC Master password when prompted.
Passwordless SSH setup on the DC Slave is complete.
Step 3: Run on the DR Machine
Run the following steps on the DR machine (172.16.13.169).
- Copy
Motadata_DCDR_Setup.shto the home directory and run it as a normal user:cp /opt/HA/Motadata_DCDR_Setup.sh ~/
cd ~
./Motadata_DCDR_Setup.sh

- Enter the same SSH username and port
22.

- Enter the DR machine's own IP address as the current server IP and enter the password.

- Enter the DC Master IP address when prompted for Server 1:
172.16.13.153. - Enter the DC Master password when prompted.
- Enter the DC Slave IP address when prompted for Server 2:
172.16.13.159. - Enter the DC Slave password when prompted.


Passwordless SSH setup on the DR machine is complete. The DC-DR setup is now fully configured.
Switchover Procedures
Two switchover scripts in /opt/HA control traffic direction between the DC and DR sites.
| Script | Purpose |
|---|---|
dr2dc_switchover | Activates the DR machine as the primary when the DC site goes down |
dc2dr_switchover | Syncs data from DR back to DC and prepares DC to resume as primary |
Run each switchover script on both the DC Master and DC Slave, and on the DR machine where indicated.
Switching Traffic from DC to DR (DC Site Down)
Follow this procedure when the DC site is unavailable and you need the DR machine to serve as the live environment.
On the DR machine, run
dr2dc_switchover.sh:./dr2dc_switchover.shEnter the DR machine ETCD IP address when prompted:
172.16.13.169.
The DR machine is now the active primary site.
Switching Traffic Back from DR to DC (DC Site Restored)
Follow this procedure when the DC site comes back online and you need to restore it as the primary.
On the DC Master, run
dc2dr_switchover.shand enter the DR ETCD IP to sync data from DR back to DC:./dc2dr_switchover.shEnter the DR machine ETCD IP address when prompted:
172.16.13.169. Wait for data sync to complete before continuing.On the DC Slave, run
dc2dr_switchover.shand enter the DR ETCD IP address.Once data sync completes on both DC machines, run
dr2dc_switchover.shon the DC Master to restore DC as the active primary.
DC side is now the active primary site again.
Troubleshooting
Use this section to diagnose common issues after completing the 4-machine DC-DR setup.
DR machine Patroni fails to join the DC cluster
Cause: The DR machine cannot reach the DC Observer ETCD on port 2379. The DR Patroni uses the DC ETCD IP, so any firewall blocking this port prevents the DR node from registering.
Fix: Confirm port 2379 is open from the DR machine to the DC Observer. Check both OS-level and network-level firewall rules:
telnet 172.16.13.163 2379
DR node does not show nofailover: true after DB configuration
Cause: The MotadataPatroniHADBConfig script did not complete successfully on the DR machine, or the reload step was skipped.
Fix: Re-run MotadataPatroniHADBConfig on the DR machine. Press Enter to accept the default PostgreSQL port and enter y at both reload prompts. Verify the cluster state after the script completes:
patronictl -c /etc/patroni/patroni.yml list
Switchover script fails with a permission error
Cause: The Motadata_DCDR_Setup.sh script was run directly from /opt/HA instead of the home directory, or it was run as root.
Fix: Copy the script to the home directory of the normal user and run it from there:
cp /opt/HA/Motadata_DCDR_Setup.sh ~/
cd ~
./Motadata_DCDR_Setup.sh
Machines cannot communicate after DC-DR setup
Cause: One or more required firewall ports are blocked between DC and DR machines.
Fix: Confirm the following ports are open between each machine pair:
| Source | Destination | Ports |
|---|---|---|
| DC Observer | DC Master and DC Slave | 80 (optional), 443, 5432, 8008 |
| DC Master and DC Slave | DC Observer | 2379, 2380, 5000, 7000 |
| DR Machine | DC Observer | 2379, 2380 |
| DC Master and DC Slave | DR Machine | 5432, 8008 |
Check both OS-level and network-level firewall rules on each machine.