Skip to main content

Installation Guide for Patroni-Based HA Deployment

Patroni-based High Availability keeps ServiceOps running without interruption. Even when a server fails, ServiceOps automatically promotes a standby database to primary and reroutes all traffic through HAProxy without manual intervention.

This guide covers Patroni and ETCD-based HA configuration for ServiceOps. Use it when your environment uses Patroni-based installer packages. Two deployment layouts are covered: a 3-machine standalone setup where the application and database share each node, and a 5-machine distributed setup where application and database run on separate dedicated machines.

This guide covers:

Take a Database Backup First
  • 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.
  • Back up your HAProxy configuration on the Observer machine from /etc/haproxy before making any changes.
Supported Platforms

This setup supports the following OS and PostgreSQL versions only:

  • OS: Ubuntu 22, Ubuntu 24, RHEL 9.4, RHEL 9.6
  • PostgreSQL: Version 16 or Version 17

How Does Patroni-Based High Availability Work?

Patroni manages the PostgreSQL Leader/Replica relationship between the Master and Slave database nodes. ETCD stores the cluster state and runs leader election. When the Master database fails, Patroni reads ETCD, promotes the Replica to Leader, and updates the cluster state automatically. HAProxy routes all database traffic to the current Patroni Leader using a health check on port 8008. The Application Observer monitors the application tier separately and triggers failover scripts when it detects the Master application is unreachable. All nodes must communicate with each other over the network for this coordination to work.


Standalone HA Deployment (3 Machines)

In this layout, each application node co-locates the ServiceOps application and the PostgreSQL database on the same server. The Observer node runs HAProxy, ETCD, and the Application Observer.

Prerequisites

Before starting, confirm the following:

  • Operating System: Ubuntu 22, Ubuntu 24, RHEL 9.4, or RHEL 9.6
  • PostgreSQL Version: 16 or 17
  • 3 machines provisioned and reachable over the network
  • ServiceOps installed on both APP + DB Node 1 and APP + DB Node 2 (follow the Standalone Installation Guide)
  • Root or sudo access on all 3 machines
  • Setup scripts extracted on their respective machines:
    • MotadataETCDSetupU24 on the Observer machine
    • MotadataPatroniSetupU24 on both APP + DB machines
    • MotadataAppHASetup on the Observer machine
  • Firewall ports open on each machine:
MachineOpen Ports
Observer80 (Optional), 443, 2379, 2380, 5000, 7000
APP + DB Node 1 and Node 280 (Optional), 443, 5432, 8008

Architecture Overview

3-machine standalone HA architecture showing the Observer Node with HAProxy, ETCD, and Application Observer, the Master Server with ServiceOps App Primary and Patroni Leader database, and the Slave Server with ServiceOps App Standby and Patroni Replica database

The 3-machine standalone layout assigns the following roles:

RoleDescriptionExample IP
Observer / HAProxy / ETCDManages load balancing, cluster coordination, and failover172.16.13.42
APP + DB Node 1 (Master)Runs the active ServiceOps application and the Patroni Leader database172.16.12.171
APP + DB Node 2 (Slave)Runs the standby ServiceOps application and the Patroni Replica database172.16.12.177

Components and Roles

  • Observer Node (HA Proxy/ETCD/Application Observer): Acts as the single entry point for all client traffic (Agents, Technicians, Requesters). HAProxy load-balances application traffic on ports 80 (optional) and 443, and routes database connections to the Patroni Leader through port 5000 and 7000. ETCD (ports 2379/2380) stores cluster state, maintains distributed consensus, and coordinates Patroni leader election. The Application Observer monitors both servers and triggers failover scripts when the Master becomes unavailable.
  • Master Server (ServiceOps App Primary + Patroni Leader Database): Active server handling all live application requests. The ServiceOps application connects to the co-located Patroni Leader database via localhost. Accessible from the Observer on ports 80 (optional) and 443; Patroni communicates on ports 5432, and 8008.
  • Slave Server (ServiceOps App Standby + Patroni Replica/Standby Database): Passive standby server kept in continuous sync with the Master and promoted automatically on failure. The ServiceOps application connects to the co-located Patroni Replica database via localhost. Port profile: 80/443 for application traffic; 5432, and 8008 for Patroni.
  • Patroni: Manages PostgreSQL high availability on both nodes. Continuously replicates the database from the Master (Leader) to the Slave (Replica) and automatically promotes the Slave to Leader if the Master fails.
  • ETCD: Distributed key-value store used for cluster coordination, service discovery, and Patroni leader election between the Observer and both servers.
  • File DB Sync: Synchronizes non-database files (attachments, patches, packages, logs) bidirectionally between Master and Slave, ensuring file-level consistency across both nodes.

Procedure

Step 1: Download Setup Files

Download the zip file containing all setup files from the Download Links page and extract it on all three machines before proceeding.

Step 2: Set Up the Observer (ETCD and HAProxy)

Run the following steps on the Observer machine (172.16.13.42).

  1. Give MotadataETCDSetupU24 execute permissions and run it:

    chmod 777 MotadataETCDSetupU24
    ./MotadataETCDSetupU24

    MotadataETCDSetupU24 installer running on the Observer machine and prompting to install ETCD

  2. Type yes when prompted to install and configure ETCD.

    Terminal showing yes entered at the ETCD install and configure prompt

  3. Enter 1 when prompted for the ETCD node number. This setup uses a single ETCD node.

    Maximum ETCD Cluster Nodes

    This setup supports a maximum of 7 ETCD cluster nodes. Leave all additional node prompts blank for a single-node setup.

    Terminal showing 1 entered at the ETCD node number prompt for a single-node setup

  4. Leave all additional ETCD node prompts blank and press Enter.

    Terminal showing blank entries at the additional ETCD node IP prompts

  5. Type yes when prompted to install and configure HAProxy.

    Terminal showing ETCD setup complete and the HAProxy installation prompt

  6. Enter the DB and APP IP addresses when prompted:

    PromptValue
    DB Node 1 IP172.16.12.171
    DB Node 2 IP172.16.12.177
    APP Node 1 IP172.16.12.171
    APP Node 2 IP172.16.12.177

    Terminal showing HAProxy configuration complete after DB and APP IP addresses are entered

ETCD and HAProxy setup 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.12.171:5432 maxconn 100 check port 8008
server etcd2 172.16.12.177:5432 maxconn 100 check port 8008

listen backend
bind *:80
balance roundrobin
mode tcp
option tcp-check
server ubuntu1 172.16.12.171:80 check port 80
server ubuntu2 172.16.12.177: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 Master Database

Run the following steps on APP + DB Node 1 / Master (172.16.12.171).

  1. Give MotadataPatroniSetupU24 execute permissions and run it:

    chmod 777 MotadataPatroniSetupU24
    ./MotadataPatroniSetupU24
  2. Enter 1 when prompted to select Node 1 or Node 2.

  3. Enter the Slave IP address when prompted: 172.16.12.177.

    Terminal showing Node 1 selected and the Slave Node 2 IP address entered for Patroni Master setup

  4. Enter the ETCD IP address when prompted: 172.16.13.42.

Patroni setup on the Master node is complete.

Step 4: Configure the Slave Database

Run the following steps on APP + DB Node 2 / Slave (172.16.12.177).

  1. Give MotadataPatroniSetupU24 execute permissions and run it:
    chmod 777 MotadataPatroniSetupU24
    ./MotadataPatroniSetupU24
  2. Enter 2 when prompted to select Node 1 or Node 2.
  3. Enter the Master IP address when prompted: 172.16.12.171.
  4. Enter the ETCD IP address when prompted: 172.16.13.42.
Verify Patroni Is Inactive on the Slave Before Continuing

After setup, confirm the Patroni service on the Slave is inactive. If it shows active or running, stop it:

systemctl stop patroni

Do not continue to Step 5 until the Slave Patroni service is inactive.

Terminal showing Patroni service status as inactive on the Slave machine after setup

Step 5: Configure the Master Application

Run the following steps on APP + DB Node 1 / Master (172.16.12.171).

  1. Copy MotadataPatroniHAMasterSlaveAppConfig from the Master /opt/HA folder to the home directory.

  2. Give it execute permissions and run it:

    chmod 777 MotadataPatroniHAMasterSlaveAppConfig
    ./MotadataPatroniHAMasterSlaveAppConfig
  3. Enter the Observer IP address when prompted: 172.16.13.42.

    Terminal showing the Observer IP address prompt during Master application configuration

  4. Enter master when asked for the machine role.

    Terminal showing master entered at the machine role prompt during application configuration

Master application configuration is complete.

Terminal showing Master application configuration completed successfully

Step 6: Configure the Slave Application

Run the following steps on APP + DB Node 2 / Slave (172.16.12.177).

  1. Copy MotadataPatroniHAMasterSlaveAppConfig from the Master /opt/HA folder to the home directory on the Slave.

  2. Give it execute permissions and run it:

    chmod 777 MotadataPatroniHAMasterSlaveAppConfig
    ./MotadataPatroniHAMasterSlaveAppConfig
  3. Enter the Observer IP address when prompted: 172.16.13.42.

  4. Enter slave when asked for the machine role.

    Terminal showing slave entered at the machine role prompt on the Slave application server

  5. Enter the Master application's DB password when prompted.

    Terminal showing the Master DB encrypted password entry on the Slave application configuration screen

DB Password Must Match

Copy the DB password directly from the Master. The password must be identical on both nodes.

Slave application configuration is complete.

Step 7: Run DB Configuration on the Master

Run the following steps on APP + DB Node 1 / Master (172.16.12.171).

  1. Retrieve the application DB password:

    cat /opt/flotomate/main-server/lib/boot-hosted-exec.conf
  2. Copy MotadataPatroniHADBConfig from /opt/HA to the home directory.

  3. Give it execute permissions and run it:

    chmod 777 MotadataPatroniHADBConfig
    ./MotadataPatroniHADBConfig
  4. Enter the DB password when prompted.

    Terminal showing the database password prompt during MotadataPatroniHADBConfig execution on the Master

  5. Enter y when asked to reload and restart Patroni members. Perform this twice and if the version is given then press enter.

    Terminal showing Patroni cluster reload and restart confirmation prompt with y entered on the Master

Master DB configuration is complete.

Step 8: Run DB Configuration on the Slave

Run the following steps on APP + DB Node 2 / Slave (172.16.12.177).

  1. Run MotadataPatroniHADBConfig:

    chmod 777 MotadataPatroniHADBConfig
    ./MotadataPatroniHADBConfig
  2. Enter the same DB password you used in Step 7.

    Terminal showing the Motadata Patroni Database Config process completed message on the Slave

    Slave DB configuration is complete.

  3. Check the status of patroni service using the command: systemctl status patroni

Remove Old HA Configuration

If an old HA configuration already exists, remove it after taking a backup:

rm -rf /opt/HA

Step 9: Configure the Application HA Observer

Run the following steps on the Observer machine (172.16.13.42).

Run as a Standard User

Run this script as a normal user. Do not use root or sudo. The script will fail if run as root.

  1. Give MotadataAppHASetup execute permissions and run it:

    chmod 777 MotadataAppHASetup
    ./MotadataAppHASetup
  2. Press Enter at every key-pair generation prompt until key generation completes.

    Terminal showing MotadataAppHASetup generating SSH key pairs on the Observer machine

  3. Enter the following values when prompted:

    PromptValue
    Username for SSHCommon SSH username for both nodes
    Port for SSHSSH port (default: 22)
    Master Server IP172.16.12.171
    Master Server PasswordEnter twice when prompted
    Slave Server IP172.16.12.177
    Slave Server PasswordEnter twice when prompted

    Terminal showing SSH username and port prompts during Application HA Observer configuration

    Terminal showing Master and Slave IP address and password prompts during HA Observer configuration

  4. Press Enter twice at the second key-pair generation prompt.

Terminal showing File Sync Installed Successfully message confirming HA Observer setup is complete

Application HA Observer configuration is complete. Verify the setup by checking logs at /opt/HA/logs.

Troubleshooting

Use this section to diagnose common issues after completing the 3-machine standalone setup.

Nginx is active on the Slave after setup

Cause: Nginx started automatically during the Slave setup. An active Nginx service on the Slave causes routing conflicts with the Observer.

Fix: Stop Nginx on the Slave and verify all services are inactive before proceeding:

systemctl stop nginx
/opt/HA permission error during setup

Cause: The /opt/HA directory is owned by a different user than the one running the setup scripts.

Fix: Correct the ownership on the affected machine:

chown -R motadata:motadata /opt/HA
Machines cannot communicate with each other

Cause: One or more required firewall ports are blocked between machines.

Fix: Confirm the following ports are open between each machine pair:

SourceDestinationPorts
ObserverAPP + DB Node 1 and Node 280 (optional), 443
ObserverAPP + DB Node 1 and Node 25432, 8008
APP + DB Node 1 (Master)Observer2379, 2380, 5000
APP + DB Node 2 (Slave)Observer2379, 2380, 5000
APP + DB Node 1 (Master)APP + DB Node 2 (Slave)5432, 8008

Check both OS-level and network-level firewall rules on each machine.


Distributed HA Deployment (5 Machines)

In this layout, the application and database tiers run on separate dedicated machines. This model combines automatic failover with independent tier scaling. Use it for large enterprises where application and database workloads must be isolated.

Prerequisites

Before starting, confirm the following:

  • Operating System: Ubuntu 22, Ubuntu 24, RHEL 9.4, or RHEL 9.6
  • PostgreSQL Version: 16 or 17
  • 5 machines provisioned and reachable over the network
  • ServiceOps installed on both APP 1 and APP 2 (follow the Standalone Installation Guide)
  • Root or sudo access on all 5 machines
  • Setup scripts extracted on their respective machines:
    • MotadataETCDSetupU24 on the Observer machine
    • MotadataPatroniSetupU24 on both DB machines
    • MotadataAppHASetup on the Observer machine
  • Firewall ports open on each machine:
MachineOpen Ports
Observer80 (Optional), 443, 2379, 2380, 5000, 7000
APP 1 and APP 280 (Optional), 443
DB 1 and DB 25432, 8008

Architecture Overview

The 5-machine distributed HA setup assigns a dedicated role to each machine:

RoleMachineExample IPPorts
Observer / HAProxy / ETCD1 machine172.16.13.4280, 443, 2379, 2380, 5000, 7000
APP 1 (Master Application)1 machine172.16.12.17180, 443
APP 2 (Slave Application)1 machine172.16.12.17780, 443
DB 1 (Master Database)1 machine172.16.12.2025432, 8008
DB 2 (Slave Database)1 machine172.16.12.2165432, 8008

HAProxy load-balances application traffic across APP 1 and APP 2 on ports 80 and 443, and routes database connections to the Patroni Leader on port 5000 and 7000. ETCD manages distributed consensus on ports 2379 and 2380. The Observer detects APP 1 failure and triggers master.sh and slave.sh failover scripts.

Procedure

Step 1: Download Setup Files

Download the zip file containing all setup files from the Download Links page and extract it on each machine before proceeding.

Step 2: Set Up the Observer (ETCD and HAProxy)

Run the following steps on the Observer machine (172.16.13.42).

  1. Give MotadataETCDSetupU24 execute permissions and run it:

    chmod 777 MotadataETCDSetupU24
    ./MotadataETCDSetupU24

    Terminal showing MotadataETCDSetupU24 script running on the Observer machine

  2. Type yes when asked whether to install and configure ETCD.

    Terminal showing the ETCD install and configure prompt with yes entered

  3. Enter 1 when asked for the ETCD node number. This setup uses a single ETCD node.

    Terminal showing 1 entered at the ETCD node number prompt for a single-node cluster

    Maximum ETCD Cluster Nodes

    This setup supports a maximum of 7 ETCD cluster nodes. Leave all additional node prompts blank for a single-node setup.

  4. Leave all additional ETCD node prompts blank and press Enter.

    Terminal showing blank entries at additional ETCD node IP prompts

  5. Type yes when asked whether to install and configure HAProxy.

    Terminal showing the HAProxy install and configure prompt

  6. Enter the DB Node 1 (Master DB) IP address, for example 172.16.12.202. Then enter the DB Node 2 (Slave DB) IP address, for example 172.16.12.216.

    Terminal showing the HAProxy configuration prompt after typing yes

    Terminal showing DB Node 1 and DB Node 2 IP address entries in the HAProxy configuration

    note

    DB Node 1 = Master DB. DB Node 2 = Slave DB.

  7. Enter the APP Node 1 (Master APP) IP address, for example 172.16.12.171. Then enter the APP Node 2 (Slave APP) IP address, for example 172.16.12.177.

    Terminal showing APP Node 1 and APP Node 2 IP address entries in the HAProxy configuration

    note

    APP Node 1 = Master APP. APP Node 2 = Slave APP.

ETCD and HAProxy setup is complete.

Verify the HAProxy Configuration

Open /etc/haproxy/haproxy.cfg and confirm it matches this structure:

HAProxy configuration file showing global, defaults, listen stats, listen postgres, and listen backend sections

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.12.202:5432 maxconn 100 check port 8008
server etcd2 172.16.12.216:5432 maxconn 100 check port 8008

listen backend
bind *:80
balance roundrobin
mode tcp
option tcp-check
server ubuntu1 172.16.12.171:80 check port 80
server ubuntu2 172.16.12.177:80 check port 80
Verify Firewall Rules

Confirm the following ports are open before continuing: 80 and 443 on the Observer and both APP machines; 2379, 2380, and 5000 on the Observer; 5432, 7000, and 8008 on both DB machines.

Verify ETCD Service Status

Check that the ETCD service is running:

systemctl status motadata_etcd

If the service is inactive, start it:

systemctl start motadata_etcd

Step 3: Configure Master DB with Patroni

Run the following steps on DB 1 (Master DB) (172.16.12.202).

  1. Give MotadataPatroniSetupU24 execute permissions and run it:

    chmod 777 MotadataPatroniSetupU24
    ./MotadataPatroniSetupU24
  2. Enter 1 when asked whether this machine is Node 1 or Node 2. Then enter the Slave DB IP address: 172.16.12.216.

    Terminal showing Node 1 selected and the Slave DB IP address entered for Patroni Master DB setup

  3. Enter the ETCD IP address when prompted: 172.16.13.42.

    Terminal showing the ETCD IP address prompt during Patroni Master DB configuration

Patroni setup on the Master DB is complete.

Step 4: Configure Slave DB with Patroni

Run the following steps on DB 2 (Slave DB) (172.16.12.216).

  1. Give MotadataPatroniSetupU24 execute permissions and run it:

    chmod 777 MotadataPatroniSetupU24
    ./MotadataPatroniSetupU24
  2. Enter 2 when asked whether this machine is Node 1 or Node 2. Enter the Master DB IP address and the ETCD IP address when prompted.

    Terminal showing Node 2 selected with Master DB and ETCD IP addresses entered for Patroni Slave DB setup

  3. Verify that the Patroni service on the Slave DB is inactive after setup:

    systemctl status patroni

    Terminal showing Patroni service status as inactive on the Slave DB after setup

    If it shows running or active, stop it:

    systemctl stop patroni
Why Must Slave Patroni Be Inactive?

Patroni on the Slave DB starts automatically during Step 5 DB configuration. Starting it early causes split-brain issues.

Step 5: Run DB Configuration on the Master DB

Run the following steps on DB 1 (Master DB) (172.16.12.202).

  1. Retrieve the application DB password from the Master APP machine:

    cat /opt/flotomate/main-server/lib/boot-hosted-exec.conf

    Terminal showing the boot-hosted-exec.conf output with the application DB password highlighted

  2. Copy MotadataPatroniHADBConfig from /opt/HA to the home directory. Give it execute permissions and run it:

    chmod 777 MotadataPatroniHADBConfig
    ./MotadataPatroniHADBConfig
  3. Enter the DB password you retrieved in step 1.

  4. Enter y when asked to reload and restart Patroni members. Perform this twice and if the version is given then press enter.

    Terminal showing the Patroni member reload and restart confirmation prompt with y entered on the Master DB

Master DB configuration is complete.

Step 6: Run DB Configuration on the Slave DB

Run the following steps on DB 2 (Slave DB) (172.16.12.216).

  1. Run MotadataPatroniHADBConfig:

    ./MotadataPatroniHADBConfig
  2. Enter the same DB password you used on the Master DB.

    Terminal showing the MotadataPatroniHADBConfig password prompt on the Slave DB

Slave DB configuration is complete.

Remove Old HA Configuration

If an old HA configuration already exists, remove it after taking a backup:

rm -rf /opt/HA

Step 7: Configure the Master Application

Run the following steps on APP 1 (Master APP) (172.16.12.171).

Copy MotadataPatroniHAMasterSlaveAppConfig from the Master DB /opt/HA folder to the Master APP machine. Give it execute permissions and run it:

chmod 777 MotadataPatroniHAMasterSlaveAppConfig
./MotadataPatroniHAMasterSlaveAppConfig
  1. Enter the Observer IP address when prompted: 172.16.13.42.

    Terminal showing the Observer IP address prompt during Master APP configuration on APP 1

  2. Enter master when asked for the machine role.

    Terminal showing master entered at the machine role prompt on APP 1

  3. Master application configuration completes.

    Terminal showing Master application configuration complete message on APP 1

Step 8: Configure the Slave Application

Run the following steps on APP 2 (Slave APP) (172.16.12.177).

Copy MotadataPatroniHAMasterSlaveAppConfig to the Slave APP machine. Give it execute permissions and run it:

chmod 777 MotadataPatroniHAMasterSlaveAppConfig
./MotadataPatroniHAMasterSlaveAppConfig
  1. Enter the Observer IP address when prompted: 172.16.13.42.

  2. Enter slave when asked for the machine role.

    Terminal showing slave entered at the machine role prompt on APP 2

  3. Enter the Master APP DB password when prompted.

    Use the Master APP DB Password

    Retrieve the DB password from the Master APP configuration file. The password must be identical on all machines.

    Terminal showing the Master APP DB password prompt on APP 2 during Slave application configuration

Slave application configuration is complete.

Step 9: Configure HA Observer for Application Failover

Run the following steps on the Observer machine (172.16.13.42).

Run as a Normal User

Run this script as a normal user. Do not use root or sudo. The script will fail if run as root.

  1. Give service_desk_ha_CI execute permissions and run it:

    chmod 777 service_desk_ha_CI
    ./service_desk_ha_CI

    Terminal showing service_desk_ha_CI starting and beginning SSH key pair generation on the Observer

  2. Press Enter repeatedly at each key-pair generation prompt until generation completes.

  3. Enter the following values when prompted:

    PromptValue
    SSH usernameOS username on both APP machines
    SSH portDefault is 22
    Master APP IP172.16.12.171

    Terminal showing SSH username, port, and Master APP IP prompts on the Observer

  4. Enter the Master APP password twice when prompted.

    Terminal showing the Master APP SSH password confirmation prompt on the Observer

  5. Enter the Slave APP IP address (172.16.12.177). Enter the Slave APP password twice when prompted.

  6. Enter test when asked for email configuration.

    Terminal showing the Slave APP IP, password, and email configuration prompts on the Observer

  7. Press Enter at the second key-pair generation prompt.

    Terminal showing the second SSH key pair generation prompt on the Observer

Observer configuration for application HA is complete. Verify the setup by checking logs:

cat /opt/HA/logs

Troubleshooting

Use this section to diagnose common issues after completing the 5-machine distributed setup.

Nginx is running on the Slave APP after setup

Cause: Nginx started automatically on APP 2 during installation. An active Nginx service on the Slave APP causes routing conflicts with the Observer.

Fix: Stop and disable Nginx on APP 2:

systemctl stop nginx
systemctl disable nginx
/opt/HA has incorrect ownership

Cause: The /opt/HA directory is owned by a different user than the one used during configuration. Failover scripts fail when they cannot write to this directory.

Fix: Correct the ownership on both Master and Slave APP machines:

chown -R motadata:motadata /opt/HA
Machines cannot communicate with each other

Cause: One or more required firewall ports are blocked between machines.

Fix: Confirm the following ports are open between each machine pair:

SourceDestinationPorts
ObserverMaster APP and Slave APP80 (optional), 443
ObserverMaster DB and Slave DB5432, 8008
Master DBObserver2379, 2380, 5000
Slave DBObserver2379, 2380, 5000
Master DBSlave DB5432, 8008

Check both OS-level and network-level firewall rules on each machine.

Patroni on Slave DB is active before Step 5

Cause: Patroni started automatically during the Slave DB Patroni setup in Step 4. Starting it before DB configuration causes split-brain issues.

Fix: Stop Patroni on the Slave DB before running Step 6:

systemctl stop patroni
HTTPS port not listening after restart

Cause: The CertificateFilePath or KeyFilePath in appsettings.json still has a leading underscore, or the file path is incorrect for the OS.

Fix: Open appsettings.json and confirm the leading underscore is removed from both CertificateFilePath and KeyFilePath. Verify the file paths exist and use the correct path separator for the OS. Restart the poller service and re-run the verification commands.

Best Practices

Follow these recommendations to keep your Patroni-based HA environment stable and recoverable.

  • Back up before every configuration change. Take a full database backup before running any HA setup script in a production environment. Restoring from backup is faster than debugging a failed configuration.
  • Synchronize time across all nodes. ETCD relies on clock consistency for leader election. Run NTP on every machine and verify clocks are in sync before starting the setup.
  • Use the same OS and PostgreSQL version on all nodes. Version drift between Master and Slave causes replication failures. Confirm all nodes run identical OS and PostgreSQL versions before proceeding.
  • Verify firewall ports before running any installer. Blocked ports are the most common setup failure. Check all required ports are open at both the OS and network level before starting Step 1.
  • Never start Patroni on the Slave manually before DB configuration runs. Patroni on the Slave must remain inactive until the DB configuration step activates it. Starting it early causes split-brain and data inconsistency.
  • Run the Application HA Observer as a non-root user. The MotadataAppHASetup and service_desk_ha_CI scripts must run as a standard OS user. Root execution causes the scripts to fail silently.
  • Keep /opt/HA owned by the same OS user on all nodes having sudo rights. Failover scripts write to this directory. Incorrect ownership prevents failover from executing. Use the user which is common in all machines and having sudo rights. You can change the ownership using the below command:
    • Syntax: chown -R <username>:<username> /opt/HA
    • Example: chown -R motadata:motadata /opt/HA
  • Monitor HAProxy stats after setup. The stats endpoint on port 7000 shows which node is currently active. Check it after setup to confirm HAProxy is routing to the correct primary node.
  • Test failover after completing setup. Simulate a Master failure in a staging environment to confirm Patroni promotes the Slave and HAProxy reroutes traffic as expected. Do not assume failover works without testing it.
  • Keep Nginx inactive on Slave application nodes. Nginx must not run on the Slave APP. An active Nginx service on the Slave causes routing conflicts with the Observer. Disable it after setup and verify it does not restart on reboot.