Skip to main content

HA Prerequisites

Requirements for converting a ProxCenter installation into a 3-node high-availability cluster. The conversion itself is driven by the wizard in Settings, High Availability tab.

Hardware

  • 3 distinct Proxmox hosts (anti-affinity: no two ProxCenter VMs on the same physical host)
  • Recommended per VM: 4 vCPU, 8 GB RAM, 50 GB disk

No watchdog device is required. The HA stack runs Patroni with watchdog: off; split-brain protection comes from etcd quorum plus strict synchronous replication, and the keepalived track_script sheds the VIP of any node whose database becomes unreachable.

Network

  • L2 connectivity between all 3 VMs (same VLAN or bridged subnet)
  • 1 free IP for the Virtual IP (VIP), on the same subnet as the 3 node IPs
  • No multicast requirement (Keepalived uses unicast VRRP)
  • Firewall rules between the 3 nodes:
PortProtocolPurposeChecked by pre-flight
2379TCPetcd clientyes (connect test node to node)
2380TCPetcd peeryes (connect test node to node)
3000TCPFrontend (HTTP)yes (local listener collision)
5432TCPPostgreSQL (Patroni replication)yes (connect test + collision)
8008TCPPatroni REST APIyes (connect test + collision)
8080TCPOrchestrator APIyes (local listener collision)
112VRRP (IP proto)Keepalived VRRPno (verify manually)

The wizard's validation step ENFORCES the TCP matrix: every node must reach both peers on 5432, 8008, 2379 and 2380, and no foreign process may already listen on 5432, 8008, 2379, 2380, 3000 or 8080 (the existing ProxCenter stack's own listeners are expected and excluded). A failed check blocks the deployment with a per-node remediation message.

Security note: etcd stores the Patroni DCS state including cluster topology. Ports 2379/2380/8008 MUST be firewalled to allow traffic only between the 3 cluster nodes. On each node:

for port in 2379 2380 8008; do
for peer in ${PEER1_IP} ${PEER2_IP} ${PEER3_IP}; do
iptables -A INPUT -p tcp --dport $port -s $peer -j ACCEPT
done
iptables -A INPUT -p tcp --dport $port -j DROP
done

Registry access (egress)

Every image in the HA stack is pulled from ghcr.io; nothing is built on the nodes. Outbound HTTPS (443) to ghcr.io (and its storage backend, *.githubusercontent.com) is the ONLY egress the conversion needs:

ImageSource
ghcr.io/adminsyspro/proxcenter-frontendProxCenter (private)
ghcr.io/adminsyspro/proxcenter-orchestratorProxCenter (private)
ghcr.io/adminsyspro/proxcenter-weasyprintProxCenter (private)
ghcr.io/adminsyspro/proxcenter-patroniProxCenter (private)
ghcr.io/adminsyspro/proxcenter-keepalivedProxCenter (private)
ghcr.io/adminsyspro/etcd:v3.5.17mirror of quay.io/coreos/etcd
ghcr.io/adminsyspro/haproxy:2.9-alpinemirror of docker.io haproxy

The private images require authentication: keep GHCR_TOKEN (and optionally GHCR_USERNAME) in node 1's .env. The wizard reads it there, runs docker login ghcr.io on nodes 2 and 3 automatically, and the validation step verifies every image manifest is pullable from every node BEFORE any destructive step runs. A missing token or unreachable image fails validation with the image and node named.

Software

  • Docker Engine 24+ and Docker Compose v2 on all 3 nodes

Secrets

All 3 nodes must share identical secret values. For in-place conversions (existing single-node), the wizard preserves and distributes node 1's existing .env values automatically. Only generate fresh values for greenfield (new) installs:

# GREENFIELD ONLY - generate once, copy to all 3 nodes' .env files:
openssl rand -base64 32 # NEXTAUTH_SECRET
openssl rand -base64 32 # APP_SECRET
openssl rand -hex 32 # ORCHESTRATOR_API_KEY
openssl rand -base64 32 # POSTGRES_PASSWORD

WARNING: For in-place conversions, node 1's existing APP_SECRET MUST be reused. It encrypts stored connection credentials; generating a new one makes all stored Proxmox/SSH credentials unreadable. The wizard handles this; only manual deployments need to copy it by hand.

TLS and external URLs (optional)

ProxCenter listens on HTTP port 3000. TLS termination is the administrator's responsibility (reverse proxy in front of the VIP). Installs already fronted by a reverse proxy / FQDN / OIDC keep their external URL through the conversion: see HA Reverse Proxy and FQDN.

Backup

Backup and PITR are the administrator's responsibility. Patroni manages replication but does NOT manage backups. The conversion writes a one-time safety dump to /opt/proxcenter/backup-pre-patroni.sql, which is NOT a backup strategy. Recommended:

  • pg_basebackup cron job from one replica
  • WAL archiving to external storage (pgBackRest or pg_probackup)
  • Test restore procedure before going live