đ Multi-Server Web Cluster & Load Balancing
Enterprise guide for deploying multiple Ring2All Web and API nodes behind Cloudflare and Nginx for high availability, zero-downtime maintenance, and horizontal scaling.
Table of Contents
Section titled âTable of Contentsâ- Architectural Overview
- Why Ring2All is 100% Stateless
- Cloudflare Load Balancing Options
- Step-by-Step Multi-Node Deployment
- Nginx Configuration on Web Nodes
- Database & Redis Clustering Requirements
- Operational Verification & Failover Testing
- Summary & Key Advantages
1. Architectural Overview
Section titled â1. Architectural OverviewâIn high-density service provider environments, the web management layer (Ring2All PBX Admin, User Portal, Switchboard Console, and BSS Client Portal) can be scaled horizontally across multiple independent Linux instances without requiring distinct domain names.
A single canonical domain (e.g., *.ring2all.com or app.ring2all.com) serves all web traffic, distributed intelligently across backend nodes by Cloudflare Edge Load Balancing:
flowchart TD
subgraph Clients["Global Ingress (Internet)"]
Browser1["Client Browser A<br/>mycompany.ring2all.com"]
Browser2["Client Browser B<br/>acme.ring2all.com"]
MobileApp["User Portal Mobile PWA"]
end
subgraph Edge["Cloudflare Anycast Global Edge Network"]
CF_WAF["Cloudflare WAF & DDoS Shield"]
CF_SSL["Universal SSL Termination (*.ring2all.com)"]
CF_LB["Cloudflare Load Balancer / Round-Robin Pool"]
end
subgraph WebCluster["Stateless Web & API Tier (Port 443 / 80)"]
Node1["Web Node 01 (198.51.100.20)<br/>Nginx + softswitch-web + softswitch-api"]
Node2["Web Node 02 (198.51.100.21)<br/>Nginx + softswitch-web + softswitch-api"]
NodeN["Web Node N (198.51.100.2N)<br/>Horizontal Scale on Demand"]
end
subgraph DataTier["Centralized State & Storage Layer"]
PG[("PostgreSQL 17 HA Cluster<br/>ss_admin | ss_telephony | ss_billing")]
Redis[("Redis Cluster / PubSub<br/>Session Cache & WebSocket Broker")]
end
subgraph TelephonyTier["Perimeter VoIP (Bypasses Web Proxy)"]
SBC["Ring2All SBC (Kamailio 6.1)<br/>sbc.ring2all.com (Port 5060/5061)"]
end
Browser1 --> CF_WAF
Browser2 --> CF_WAF
MobileApp --> CF_WAF
CF_WAF --> CF_SSL
CF_SSL --> CF_LB
CF_LB -- "Round-Robin / Health Check" --> Node1
CF_LB -- "Round-Robin / Health Check" --> Node2
CF_LB -- "Round-Robin / Health Check" --> NodeN
Node1 --> PG
Node2 --> PG
NodeN --> PG
Node1 --> Redis
Node2 --> Redis
NodeN --> Redis
2. Why Ring2All is 100% Stateless
Section titled â2. Why Ring2All is 100% StatelessâUnlike legacy PBX platforms that store web sessions in server memory files (/tmp/sess_*), Ring2Allâs application tier is designed with zero in-memory session lock-in:
- Cryptographic JWT Authentication (Stateless):
- When an administrator or tenant user logs in, the API issues a signed JSON Web Token (JWT).
- Any Web Node can decode and cryptographically verify the token using the shared cluster secret key (
JWT_SECRET). - Request #1 can hit Web Node 01 and Request #2 can hit Web Node 02 without requiring sticky sessions or session re-authentication.
- Single Page Application (SPA) Decoupling:
- The frontend interfaces (
softswitch-web,softswitch-portal,softswitch-switchboard,softswitch-bss-client) compile into static HTML5, CSS3, and JavaScript bundles. - Static assets are heavily cached across Cloudflareâs 300+ Edge data centers. Over 80% of asset requests never reach your origin servers.
- The frontend interfaces (
- Centralized Data & Cache Tier:
- Real-time events, WebSockets, and database transactions are offloaded to PostgreSQL 17 and Redis, leaving the Node.js Fastify API threads free to execute sub-millisecond JSON operations.
3. Cloudflare Load Balancing Options
Section titled â3. Cloudflare Load Balancing OptionsâYou can implement multi-server web distribution using either of the following two Cloudflare configurations:
Option A: Cloudflare Anycast Round-Robin (100% Free on all Cloudflare Plans)
Section titled âOption A: Cloudflare Anycast Round-Robin (100% Free on all Cloudflare Plans)âBy creating multiple A records with the same hostname pointing to distinct server IPs, Cloudflare distributes incoming HTTPS connections evenly across your origins:
| Record Type | Host / Name | Origin Server IP | Cloudflare Proxy Status |
|---|---|---|---|
| A | * (Wildcard) |
198.51.100.20 (Web Node 01) |
âď¸ Proxied (Orange Cloud) |
| A | * (Wildcard) |
198.51.100.21 (Web Node 02) |
âď¸ Proxied (Orange Cloud) |
| A | * (Wildcard) |
198.51.100.22 (Web Node 03) |
âď¸ Proxied (Orange Cloud) |
- How it works: Cloudflare Anycast automatically balances client HTTP sessions among the configured origin IPs.
- Cost: Included at zero additional charge in standard Cloudflare accounts.
Option B: Cloudflare Load Balancer (With Active Health Checks & Auto-Failover)
Section titled âOption B: Cloudflare Load Balancer (With Active Health Checks & Auto-Failover)âFor mission-critical telecom carriers, the Cloudflare Load Balancing add-on provides automated health monitoring and sub-3-second failover:
- Origin Pool Configuration:
- Create pool:
ring2all-web-cluster. - Add Origins:
node-01(198.51.100.20),node-02(198.51.100.21). - Weight:
1:1(or customized by server capacity).
- Create pool:
- Health Monitor:
- Path:
/health(or/api/health). - Expected Response Code:
200 OK. - Interval: Every
15 seconds. - Timeout:
3 seconds.
- Path:
- Autonomous Failover:
- If
node-01fails or undergoes routine OS maintenance, Cloudflare automatically stops routing requests to it within 3 seconds. - Zero User Interruption: 100% of traffic immediately routes to
node-02without connection dropouts or 502 Bad Gateway errors.
- If
4. Step-by-Step Multi-Node Deployment
Section titled â4. Step-by-Step Multi-Node DeploymentâStep 1: Provision Web Server Instances
Section titled âStep 1: Provision Web Server InstancesâDeploy 2 or more Linux servers (Debian 13 or Ubuntu 24.04 LTS) with standard system specs:
- vCPU: 4 cores.
- RAM: 8 GB.
- Disk: 50 GB NVMe SSD.
Step 2: Install Ring2All Web & API Packages
Section titled âStep 2: Install Ring2All Web & API PackagesâOn each web node, install the system packages:
# Update repository and install application packagessudo apt updatesudo apt install -y softswitch-web softswitch-api softswitch-portal softswitch-switchboard nginxStep 3: Synchronize Cluster Secrets in .env
Section titled âStep 3: Synchronize Cluster Secrets in .envâEnsure that /opt/softswitch-api/.env on all web nodes contains identical cryptographic and database credentials:
# /opt/softswitch-api/.env (Must match across ALL Web Nodes)NODE_ENV=productionPORT=3000HOST=127.0.0.1
# Shared Cryptographic JWT Key (CRITICAL: Must be identical)JWT_SECRET="r2a_prod_super_secret_cluster_token_98374291834"
# Centralized PostgreSQL 17 Cluster ConnectionDATABASE_URL="postgres://ring2all_app:SecureClusterPass@192.168.10.31:5432/ss_telephony"ADMIN_DATABASE_URL="postgres://ring2all_app:SecureClusterPass@192.168.10.31:5432/ss_admin"BILLING_DATABASE_URL="postgres://ring2all_app:SecureClusterPass@192.168.10.31:5432/ss_billing"
# Shared Redis ClusterREDIS_HOST="192.168.10.31"REDIS_PORT=6379REDIS_PASSWORD="ClusterRedisAuthPass2026"Step 4: Enable and Start Systemd Services
Section titled âStep 4: Enable and Start Systemd ServicesâOn each web node:
sudo systemctl daemon-reloadsudo systemctl enable --now softswitch-apisudo systemctl restart nginx5. Nginx Configuration on Web Nodes
Section titled â5. Nginx Configuration on Web NodesâEvery web node runs a lightweight local Nginx reverse proxy that handles incoming traffic forwarded from Cloudflare:
server { listen 80; listen [::]:80; server_name *.ring2all.com ring2all.com;
# Trust Cloudflare proxy IP headers set_real_ip_from 173.245.48.0/20; set_real_ip_from 103.21.244.0/22; set_real_ip_from 103.22.200.0/22; set_real_ip_from 103.31.4.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 108.162.192.0/18; set_real_ip_from 190.93.240.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17; set_real_ip_from 162.158.0.0/15; set_real_ip_from 104.16.0.0/13; set_real_ip_from 104.24.0.0/14; set_real_ip_from 172.64.0.0/13; set_real_ip_from 131.0.72.0/22; real_ip_header CF-Connecting-IP;
# Static Web Frontend root /opt/softswitch-web/dist; index index.html;
# Gzip Compression gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# Health Check Endpoint for Cloudflare Load Balancer location = /health { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; }
# API Proxy location /api/ { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; proxy_connect_timeout 3s; proxy_read_timeout 60s; }
# SPA Routing Fallback location / { try_files $uri $uri/ /index.html; }}6. Database & Redis Clustering Requirements
Section titled â6. Database & Redis Clustering RequirementsâTo sustain thousands of concurrent web requests across multiple nodes without connection pool starvation:
- PostgreSQL Connection Pool Optimization (
pgbouncer):- Install
pgbounceron the PostgreSQL database cluster to manage thousands of lightweight connection handles from all web nodes. - Configure transaction pooling mode (
pool_mode = transaction) inpgbouncer.ini.
- Install
- Redis Centralized Cache:
- Configure Redis persistence (
appendonly yes) or Redis Sentinel for high availability. - Real-time WebSocket notifications (active call dashboards, BLF state changes) broadcast over Redis Pub/Sub so that a user connected to Node 01 instantly receives state updates generated by Node 02.
- Configure Redis persistence (
7. Operational Verification & Failover Testing
Section titled â7. Operational Verification & Failover Testingâ1. Verify Node Health Locally
Section titled â1. Verify Node Health LocallyâOn each individual web node, execute:
curl -I http://127.0.0.1/health# Expected: HTTP/1.1 200 OK
curl -I http://127.0.0.1/api/health# Expected: HTTP/1.1 200 OK2. Verify Cloudflare Edge Load Balancing
Section titled â2. Verify Cloudflare Edge Load BalancingâFrom an external computer, inspect the HTTP headers:
curl -svo /dev/null https://app.ring2all.com/health# Expected:# < HTTP/2 200# < cf-ray: ...# < server: cloudflare3. Simulate Node Failure (Zero-Downtime Test)
Section titled â3. Simulate Node Failure (Zero-Downtime Test)â- Stop the web service on Node 01:
Terminal window sudo systemctl stop nginx - Immediately browse to
https://app.ring2all.comor send 100 consecutive HTTP requests viaab/wrk. - Cloudflare automatically shunts 100% of traffic to Node 02. The user session remains completely active with zero errors.
- Restart Node 01:
Terminal window sudo systemctl start nginx - Cloudflare automatically resumes traffic distribution to Node 01 within 15 seconds.
8. Summary & Key Advantages
Section titled â8. Summary & Key Advantagesâ| Feature / Benefit | Single Server | Multi-Server with Cloudflare |
|---|---|---|
| Domain Management | 1 Domain | Identical Single Domain (*.ring2all.com) |
| High Availability | None (Single Point of Failure) | Active-Active Cluster (N+1) |
| DDoS & Web Shield | Local iptables/nftables only | Enterprise Cloudflare Global WAF |
| Maintenance Downtime | Requires scheduled outages | Zero-Downtime Rolling Restarts |
| VoIP Telephony Impact | Co-located on same box | VoIP completely isolated on Kamailio SBC |
| Horizontal Scalability | Vertical upgrade only | Add new web nodes in < 5 minutes |

