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 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: Move to DC side master application machine
- Execute the MotadataHAFileSync setup.

- Upon executing it will ask for Current Server IP address.

Enter IP address of the current machine, in this scenario 172.16.13.153

Next it will ask for server 1 IP address

Enter slave application machine IP address in this scenario 172.16.13.159

Next it will ask for Server 2 IP address

Here Enter DR side application machine IP address in this scenario 172.16.13.169

Next, it will ask for username, enter username which is common on all machines and have sudo access.

Next it will ask for password for that user

Enter password here
Password will not be visible at this step as it is suppressed due to security.
Next it will ask for port number for SSH

Enter 22 for default

Next it will ask for DB node of the current machine

Enter IP address for the DB machine of the current node, here it is in same machine so enter current machine IP address => 172.16.13.153

Upon entering DB node ip address your file sync setup is completed

After completing this setup check for the below mentioned service:
Command: systemctl status lsyncd
If found inactive, start it using the below command:
Command: systemctl start lsyncd

Check for cronjob entry using crontab --l

Step 8: Move to DC side slave application machine
Execute the MotadataHAFileSync setup using the below command:
./MotadataHAFileSync

Similarly it will ask for current machine IP address.

Enter Current machine IP address here 172.16.13.159.

Next it will ask for server 1 IP address.

Enter master application machine IP address in this scenario 172.16.13.153

Next it will ask for Server 2 IP address.

Here, enter DR side application machine IP address in this scenario 172.16.13.169.

Next, it will ask for username, Enter username which is common on all machines and have sudo access.

Next it will ask for password for that user

Enter password here.
Password will not be visible at this step as it is suppressed due to security.
Next it will ask for port number for SSH

Enter 22 for default.

Next it will ask for DB node of the current machine.

Enter IP addrress for the DB machine of the current node, Here it is in same machine so enter 172.16.13.159

Upon entering DB node ip address your file sync setup is completed.

After completing this setup check for below mentioned service:
Command: systemctl status lsyncd
If found active, stop it using the below command:
systemctl stop lsyncd
Check for cronjob entry using crontab --l

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: Move to DC side master application machine
Execute the MotadataHAFileSync setup file.

Upon executing it will ask for Current Server IP address.

Enter IP address of the current machine, in this scenario 172.16.13.169

Next, it will ask for server 1 IP address.

Enter DC side master machine IP here 172.16.13.153.

Next, it will ask for server 2 IP address.

Enter DC side slave machine IP here 172.16.13.159.

Next, it will ask for username.

Enter username which is common on all the machines and does have sudo rights. Here flotomate is used.

Upon entering username it will ask for password of that user.

Enter password here.
Password will not be visible at this step as it is suppressed due to security.
Next it will ask for port number for SSH.

Enter 22 for default.

Next it will ask for DB node of the current machine.

Enter IP address for the DB machine of the current node, here it is in same machine so enter current machine IP address, 172.16.13.169.

Upon entering DB node ip address your file sync setup is completed.

After completing this setup check for below mentioned service
Command: systemctl status lsyncd
If found active, stop it using the below command:
systemctl stop lsyncd
Check for cronjob entry using crontab -l
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.
Switchover Procedures
The DCDR_SwitchOver utility manages all reconfiguration for both directions of switchover. Run it on the appropriate machine for each phase of the procedure.
The utility presents two options when launched:
- DC to DR (
1): Reconfigures the local Patroni node to sync from the specified ETCD cluster (demotes the node to a replica). - DR to DC (
2): Promotes the local Patroni node to the active primary role and connects it to the specified ETCD cluster.

Each switchover phase requires downtime. Take a full database backup before starting Phase 3. Confirm there is no data discrepancy between sites before switching traffic back.
Phase 1: DC Site Is Down, Promote DR to Primary
Run this phase on the DR machine (172.16.13.169) when the DC site is unresponsive.
Run the switchover utility:
cd /opt/HA
./DCDR_SwitchOverEnter
2at the choice prompt to select DR to DC.
Enter the DR machine's ETCD IP address when prompted:
172.16.13.169.

The utility processes
/etc/patroni/config.yml, creates a backup, and displays the current cluster state. When prompted to reload members, enterY.Press Enter when asked for the restart time to accept
now.Enter
yto confirm the restart.Press Enter at the PG version prompt to accept the default.

The DR site is now the active primary. The switchover utility only reconfigures the database. Start the ServiceOps application services on the DR machine separately after this step completes.
Phase 2: DC Site Recovers, Rejoin DC Nodes as Replicas
Run this phase after the DC site comes back online. This syncs the DC master and DC slave to receive data from the DR site, which is now the active primary.
Phase 2.1: Rejoin the DC Master as a Replica
Run the following steps on the DC Master (172.16.13.153).
Run the switchover utility:
cd /opt/HA
./DCDR_SwitchOverEnter
1at the choice prompt to select DC to DR.
Enter the DR site ETCD IP address when prompted:
172.16.13.169.

The utility processes the Patroni config and displays the current cluster state.

Follow the same reload and restart steps as in Phase 1: enter
Yto reload, Enter fornow,yto confirm, and Enter for the PG version prompt.
The DC master has rejoined the cluster as a replica syncing from the DR site.
Phase 2.2: Rejoin the DC Slave as a Replica
Run the following steps on the DC Slave (172.16.13.159).
Run the switchover utility:
cd /opt/HA
./DCDR_SwitchOver
Enter
1at the choice prompt to select DC to DR.Enter the DR site ETCD IP address when prompted:
172.16.13.169.Follow the same reload and restart steps as in Phase 2.1.
The DC slave has rejoined the cluster as a replica. DC is now acting as DR, and the DR site is handling all traffic.
Phase 3: Switch Traffic Back to Original DC
Run this phase when you are ready to restore normal operations with the original DC site as primary. This phase requires downtime. Confirm there is no data discrepancy and take a database backup before starting.
Phase 3.1: Promote the DC Master Back to Primary
Run the following steps on the DC Master (172.16.13.153).
Run the switchover utility:
cd /opt/HA
./DCDR_SwitchOver
Enter
2at the choice prompt to select DR to DC.
Enter the DC Observer ETCD IP address when prompted:
172.16.13.163.

The utility processes the Patroni config with the DC ETCD IP.

Follow the same reload and restart steps as in earlier phases.

The DC master is now the active primary again.
Phase 3.2: Rejoin the DC Slave Under the DC Master
Run the following steps on the DC Slave (172.16.13.159).
Run the switchover utility:
cd /opt/HA
./DCDR_SwitchOver
Enter
2at the choice prompt to select DR to DC.Enter the DC Observer ETCD IP address when prompted:
172.16.13.163.Follow the same reload and restart steps as in Phase 3.1.
The DC slave rejoins as a replica under the DC master.
Phase 3.3: Switch the DR Machine Back to a Replica
Run the following steps on the DR machine (172.16.13.169).
Run the switchover utility:
cd /opt/HA
./DCDR_SwitchOver
Enter
1at the choice prompt to select DC to DR.
Enter the DC Observer ETCD IP address when prompted:
172.16.13.163.

The utility processes the Patroni config.

Follow the same reload and restart steps as in earlier phases.

The DR machine is now a replica syncing from the DC site. Normal operations are fully restored.
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.