Why host HAProxy on a dedicated VPS?
HAProxy (High Availability Proxy) is an open source load balancing and TCP/HTTP proxy software recognized for its production performance. Hosting it on a dedicated VPS lets you centralize traffic distribution among your application servers, ensure service continuity in case of node failure, and fine-tune routing rules without license fees. On a single 2 vCPU / 2 GB RAM VPS, HAProxy effortlessly handles thousands of simultaneous connections. It is the preferred solution of technical teams who want a robust, controlled infrastructure at a managed cost.
What you can do with HAProxy
- Distribute HTTP/HTTPS traffic among several application servers with configurable algorithms (roundrobin, leastconn, source…)
- Set up a reverse proxy to expose several internal services behind a single public IP address
- Monitor backend health with automatic health checks and remove a failing server without service interruption
- Terminate SSL/TLS connections at the front end (offloading) to relieve your application servers from encryption
- Route traffic by domain or path with ACLs (host_hdr, path_beg) on a single port 443
- Consult real-time traffic statistics via HAProxy's built-in web interface (stats uri /stats)
Install and configure HAProxy on your ServOrbit VPS
Order a ServOrbit Cloud VPS and launch the installation
Go to /vps-cloud and choose a plan with at least 2 vCPU and 2 GB RAM. From your VPS dashboard, open the Marketplace, search for 'HAProxy' and click Install. ServOrbit's automatic provisioning installs HAProxy via apt and enables the service — no SSH connection required at this stage. You can also install manually:
sudo apt update && sudo apt install -y haproxyUnderstand the structure of haproxy.cfg
The main configuration file is at
/etc/haproxy/haproxy.cfg. It is organized into four sections:global(process, logs, system limits),defaults(inherited timeouts and modes),frontend(listening ports, ACL rules) andbackend(target servers, algorithm, health checks). Edit it with:sudo nano /etc/haproxy/haproxy.cfgConfigure a complete HTTP/HTTPS frontend and backend
Here is a complete configuration for two application servers with SSL termination:
global log /dev/log local0 maxconn 50000 user haproxy group haproxy defaults log global mode http option httplog timeout connect 5s timeout client 30s timeout server 30s frontend http_front bind *:80 redirect scheme https code 301 frontend https_front bind *:443 ssl crt /etc/haproxy/certs/bundle.pem default_backend app_servers backend app_servers balance roundrobin option httpchk GET /health server app1 192.168.1.10:3000 check weight 1 inter 2s fall 3 rise 2 server app2 192.168.1.11:3000 check weight 2 inter 2s fall 3 rise 2The
weightparameter sends proportionally more traffic to app2. Theoption httpchk GET /healthdirective sends an HTTP request to the/healthendpoint of each backend to verify it responds correctly.Configure ACLs for domain and path-based routing
ACLs allow routing traffic to different backends based on the domain name or request path. Add to your frontend:
frontend https_front bind *:443 ssl crt /etc/haproxy/certs/bundle.pem acl host_api hdr(host) -i api.mysite.com acl host_app hdr(host) -i app.mysite.com acl path_admin path_beg /admin use_backend api_servers if host_api use_backend admin_servers if path_admin use_backend app_servers if host_app default_backend app_serversThe
hdr(host)directive inspects the HTTP Host header to identify the domain.path_beg /adminroutes all requests whose path starts with/adminto a dedicated backend.Terminate SSL/TLS with Let's Encrypt and create the PEM bundle
HAProxy expects a
.pemfile containing the certificate, the intermediate chain and the private key in that order. After obtaining your certificate with Certbot, create the bundle:sudo mkdir -p /etc/haproxy/certs sudo cat /etc/letsencrypt/live/mysite.com/fullchain.pem \ /etc/letsencrypt/live/mysite.com/privkey.pem \ | sudo tee /etc/haproxy/certs/bundle.pem sudo chmod 600 /etc/haproxy/certs/bundle.pemTo automate renewal, add a post-hook in
/etc/letsencrypt/renewal-hooks/post/haproxy.shthat rebuilds the bundle and runssystemctl reload haproxy.Enable the HAProxy statistics page
The built-in statistics page gives a real-time view of each frontend, backend and server. Add a dedicated frontend block:
frontend stats bind *:8404 stats enable stats uri /stats stats refresh 10s stats auth admin:SecretPassword stats hide-versionAccess it at
http://your-ip:8404/stats. Thestats authfield protects the page with HTTP Basic authentication.Validate the configuration and reload without interruption
Before any reload, validate the configuration file syntax:
sudo haproxy -c -f /etc/haproxy/haproxy.cfgIf the command displays
Configuration file is valid, reload HAProxy without dropping active connections:sudo systemctl reload haproxyCheck that the service is active:
sudo systemctl status haproxy. Thereloadcommand (notrestart) guarantees a graceful reload: established connections finish normally before the old workers stop.Check logs and monitor continuously
HAProxy sends its logs to syslog. View them in real time:
sudo journalctl -u haproxy -fEach line shows the frontend, backend, selected server, HTTP code and connection times — essential for diagnosing a routing issue or slow backend.
Advanced health checks: detecting failing backends
The check directive on each server line enables health checks. By default, HAProxy opens a TCP connection to verify the port responds. To go further, option httpchk GET /health sends a real HTTP request and waits for a 2xx code. The parameters inter 2s fall 3 rise 2 mean: check every 2 seconds, remove the server after 3 consecutive failures, reintegrate it after 2 successes. This combination ensures a backend in error is excluded from the pool within 6 seconds at most. Add option redispatch so HAProxy retries failed requests on another pool server — essential for transparent failover.
Load balancing algorithms: which one to choose?
Scroll the table
| Algorithm | Behavior | Ideal for |
|---|---|---|
| roundrobin | Distributes requests in turn between servers. Supports the weight parameter. | Backends with equivalent capacities |
| leastconn | Sends each new request to the server with the fewest active connections. | Long connections (WebSocket, database) |
| source | Hashes the client source IP for session persistence without a cookie. | Sessions that cannot be shared between backends |
| uri | Hashes the request URI to always route to the same backend. | Application caches where data locality matters |
Troubleshooting: common errors and solutions
Here are the five most common errors when configuring or reloading HAProxy, with their cause and steps to fix them.
Common errors and how to resolve them
[ALERT] Starting frontend http_front: cannot bind socket [0.0.0.0:80]— Port 80 is already used by another process (nginx, apache2). Identify it withsudo ss -tlnp | grep ':80', stop the competing service (sudo systemctl stop nginx) then reload HAProxy.[WARNING] Server app_servers/app1 is DOWN, reason: Layer4 connection problem— HAProxy cannot reach the backend IP address or port. Check the application server is running, its firewall allows connections from the HAProxy VPS IP, and the address inhaproxy.cfgis correct.[ALERT] parsing [/etc/haproxy/haproxy.cfg:42] : unknown keyword 'serveur'— Syntax error in the configuration file. The commandhaproxy -c -f /etc/haproxy/haproxy.cfggives the exact line number. HAProxy keywords are in English:server,frontend,backend. Also check indentation (HAProxy only accepts spaces).[ALERT] ssl library has no cert for frontend https_frontor certificate expired — The bundle.pem file is missing, empty or contains an expired certificate. Rebuild the bundle from up-to-date Let's Encrypt files (fullchain.pem+privkey.pem) then reload.- Statistics page returns HTTP 403 — The
stats authdirective is configured but credentials are not sent, or the source IP is not in astats allow-fromwhitelist. Check the URL (/statsby default), the credentials, and temporarily addstats allow-from 0.0.0.0/0to diagnose.
Tip: after each modification to haproxy.cfg, always run sudo haproxy -c -f /etc/haproxy/haproxy.cfg before systemctl reload. This syntax validation takes under a second and prevents a service interruption if the file contains an error.
Going further
The official HAProxy documentation details all directives, advanced TCP options, QUIC/HTTP3 support (HAProxy 2.6+) and high availability configuration with Keepalived for virtual IP failover between two HAProxy instances. This guide covers going live on a ServOrbit VPS; the vendor documentation remains the reference for fine-tuning.