How to Install and Configure HAProxy Load Balancer on Ubuntu Server
Sep 06, 2026
•
By Alex Grant


High availability and fault tolerance are the backbone of any scalable web application. When a single web server goes down or struggles under peak traffic, your users experience downtime, latency, and broken sessions.
Deploying HAProxy (High Availability Proxy) is one of the most reliable ways to solve this. As an open-source, ultra-fast TCP/HTTP load balancer and reverse proxy, HAProxy distributes incoming client requests across multiple backend web servers. It performs automated health checks, absorbs traffic spikes, and ensures zero downtime if an individual node fails.
This step-by-step guide covers how to install, configure, and secure HAProxy on an Ubuntu server, complete with health checks and an interactive stats monitoring dashboard.
Prerequisites and Architecture Overview
Before starting, ensure you have:
- 1 Load Balancer Server: Ubuntu 22.04 LTS or 24.04 LTS with a public IP (e.g.,
192.0.2.10). A high-performance, low-latency node such as a Hostomy Cloud VPS works ideally here to handle routing and SSL termination without bottlenecks. - 2 Backend Web Servers: Two instances running Apache, Nginx, or a custom application runtime (e.g., Node.js, Go) with internal or public IPs:
- Backend 1:
192.0.2.21 - Backend 2:
192.0.2.22 - Root or sudo privileges across all nodes.
- A registered domain name pointing to your load balancer’s public IP (optional, but required for HTTPS/SSL termination).
Incoming Client Traffic
│
▼
┌─────────────────────┐
│ HAProxy Server │
│ (192.0.2.10) │
└──────────┬──────────┘
│
┌───────────┴───────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Backend Node 1 │ │ Backend Node 2 │
│ (192.0.2.21:80) │ │ (192.0.2.22:80) │
└──────────────────┘ └──────────────────┘
Step 1: Update Your System and Install HAProxy
SSH into your designated HAProxy server and update the local package index to ensure you pull the latest security patches:
sudo apt update && sudo apt upgrade -y
Install HAProxy from the official Ubuntu repository:
sudo apt install haproxy -y
Once the installation finishes, verify the installed version and ensure the service is running:
haproxy -v sudo systemctl status haproxy
Enable HAProxy to start automatically on system boot:
sudo systemctl enable haproxy
Step 2: Understand the HAProxy Configuration Structure
HAProxy stores its primary configuration in /etc/haproxy/haproxy.cfg. Before modifying it, create a backup of the default configuration file:
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
The configuration is split into distinct functional sections:
global: Defines process-wide security and system performance parameters (e.g., user, group, chroot jail, and max connection limits).defaults: Sets fallback parameters (timeouts, log settings, mode) inherited by frontend and backend sections.frontend: Defines how requests are received (listening IPs, ports, SSL certs, and rules directing traffic to backends).backend: Defines the cluster of target servers that fulfill requests, along with load balancing algorithms and health check intervals.listen: Combines frontend and backend logic into a single block (commonly used for administrative dashboards like HAProxy Stats).
Step 3: Configure Load Balancing for HTTP Traffic
Open the configuration file using your preferred editor:
sudo nano /etc/haproxy/haproxy.cfg
Leave the default global and defaults sections intact unless you need custom log formatting or tuned timeouts. Scroll to the bottom of the file and append your custom Frontend and Backend definitions:
# --------------------------------------------------
# Frontend: Accepts public HTTP traffic on port 80
# --------------------------------------------------
frontend http_in
bind *:80
mode http
option httplog
option forwardfor
default_backend web_cluster
# --------------------------------------------------
# Backend: Balances traffic across app nodes
# --------------------------------------------------
backend web_cluster
mode http
balance roundrobin
option httpchk GET /
http-check expect status 200
cookie SERVERID insert indirect nocache
server web1 192.0.2.21:80 check cookie web1
server web2 192.0.2.22:80 check cookie web2
Key Directives Explained:
bind *:80: Listens on port 80 across all available network interfaces.option forwardfor: Appends theX-Forwarded-Forheader so backend servers can log client IP addresses rather than the load balancer's IP.balance roundrobin: Distributes incoming requests sequentially between backend nodes. Alternative algorithms include:leastconn: Sends requests to the node with the fewest active connections (ideal for long-running database or WebSocket connections).source: Hashes client IP addresses to ensure a user repeatedly reaches the same server without cookie manipulation.option httpchk GET /&http-check expect status 200: Periodically queries/on backend servers. If a server returns an error or times out, HAProxy immediately drops it from rotation.check: Enables continuous TCP/HTTP health probes on that individual server line.
Save the file and exit the editor (Ctrl + O, Enter, then Ctrl + X).
Step 4: Enable the HAProxy Statistics Dashboard
HAProxy includes a built-in web portal that provides real-time visibility into traffic throughput, node availability, session counts, and server status.
Reopen /etc/haproxy/haproxy.cfg and append the following listen block:
# --------------------------------------------------
# Admin Stats Dashboard
# --------------------------------------------------
listen stats
bind *:8404
mode http
stats enable
stats uri /
stats refresh 10s
stats admin if TRUE
stats auth admin:StrongPassword123!
Security Note: Replace StrongPassword123! with a secure password, and avoid using standard defaults on production networks.Step 5: Validate Configuration and Restart HAProxy
HAProxy provides a syntax validation flag (-c). Run it before restarting the daemon to prevent syntax mistakes from taking down active services:
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
If the terminal returns:
Configuration file is valid
Restart the HAProxy systemd service to apply your changes:
sudo systemctl restart haproxy
Step 6: Configure Firewall (UFW) Rules
If you have Uncomplicated Firewall (UFW) active on Ubuntu, permit traffic for standard HTTP, HTTPS, and your custom stats port:
sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw allow 8404/tcp sudo ufw reload
If you manage nodes in private subnets, restrict port 8404 so only your internal office IP or VPN subnet can access the dashboard.
Step 7: Test Load Balancing and Failover
1. Test Traffic Routing
To verify load balancing, ensure each backend web server serves a page identifying its host. On Backend 1, place an index.html file displaying "Served by Web 1", and on Backend 2, place "Served by Web 2".
From an external workstation, send consecutive requests to your HAProxy IP:
curl http://192.0.2.10/ curl http://192.0.2.10/
You should see alternate responses:
Served by Web 1 Served by Web 2
2. Test Automated Failover
Simulate an outage by stopping the web server service on Backend 1:
# Run on Backend 1: sudo systemctl stop nginx
Now, curl your load balancer repeatedly. HAProxy will detect the failed health check within seconds, drop Backend 1 from the pool, and route 100% of traffic seamlessly to Backend 2 without dropping visitor requests.
3. Access the Stats Page
Navigate to [http://192.0.2.10:8404/](http://192.0.2.10:8404/) in your browser. Enter your credentials (admin / StrongPassword123!). Backend 1 will appear highlighted in red (DOWN), while Backend 2 will remain green (UP).
Step 8: Configure SSL/TLS Termination (HTTPS)
Terminating SSL at the load balancer level offloads heavy encryption and decryption tasks from backend nodes, freeing up their compute capacity.
1. Install Certbot
Install Certbot with the standalone plugin:
sudo apt install certbot -y
2. Generate a Let's Encrypt Certificate
Temporarily stop HAProxy so Certbot can listen on port 80 to complete the ACME challenge:
sudo systemctl stop haproxy sudo certbot certonly --standalone -d example.com -d www.example.com
3. Bundle the Certificate and Private Key
HAProxy requires the complete certificate chain and private key concatenated into a single .pem file:
sudo mkdir -p /etc/haproxy/certs sudo bash -c 'cat /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem > /etc/haproxy/certs/example.com.pem' sudo chmod 600 /etc/haproxy/certs/example.com.pem
4. Update the HAProxy Frontend for HTTPS
Open /etc/haproxy/haproxy.cfg and update the frontend block to redirect HTTP to HTTPS and terminate SSL:
frontend http_in
bind *:80
mode http
redirect scheme https code 301 if !{ ssl_fc }
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
mode http
option httplog
option forwardfor
http-request set-header X-Forwarded-Proto https
default_backend web_cluster
Validate and restart the service:
sudo haproxy -c -f /etc/haproxy/haproxy.cfg sudo systemctl start haproxy
Your load balancer now enforces secure HTTPS connections across all incoming traffic.
Production Best Practices
- Tune System File Limits: For high-throughput setups handling tens of thousands of concurrent connections, increase maximum open file descriptors in
/etc/security/limits.conf: - Plaintext
haproxy soft nofile 65536 haproxy hard nofile 65536
- Implement Connection Throttling: Prevent brute-force attempts and DoS spikes by applying rate-limiting stick tables directly inside your HAProxy frontend.
- Automate Certificate Renewal: Add a post-renewal hook script in
/etc/letsencrypt/renewal-hooks/post/that re-concatenates the.pemfile and reloads HAProxy (systemctl reload haproxy) without downtime.
Reliable load balancing depends heavily on consistent network throughput, low latency, and rock-solid underlying hardware. If you are building out redundant infrastructure, deploying your load balancers and application nodes on Hostomy VPS Hosting delivers the dedicated CPU resources, NVMe storage performance, and reliable uplink speeds required to keep mission-critical workloads running smoothly.