To create HAProxy on a Linux server, install HAProxy via your distro’s package manager, define a frontend on ports 80/443 and backends for your app servers in /etc/haproxy/haproxy.cfg, enable health checks, start and enable the service with systemd, open your firewall, then test routing and SSL termination. See the step-by-step guide below.
If you’re searching for how to create HAProxy on Linux Server, this guide walks you through installation, configuration, SSL termination, sticky sessions, ACLs, and troubleshooting. Whether you run Ubuntu, Debian, or RHEL/CentOS/AlmaLinux, you’ll learn a production-ready setup that scales web traffic reliably and securely.
What is HAProxy and Why Use it?
HAProxy is a high-performance, open-source TCP/HTTP load balancer and reverse proxy. It distributes traffic across multiple backend servers, improves uptime with health checks, supports sticky sessions, rate limiting, SSL/TLS termination, HTTP/2, and granular routing rules.

It’s a go-to choice for web apps, APIs, and microservices needing scalability and fault tolerance.
Prerequisites
- A Linux server (Ubuntu/Debian or RHEL/CentOS/AlmaLinux) with sudo access
- Domain name (recommended) pointing to the HAProxy server’s IP
- At least two backend application servers (e.g., 10.0.0.10:80 and 10.0.0.11:80)
- Open ports: 80 (HTTP), 443 (HTTPS) on the load balancer
- Basic command-line familiarity
Step-by-Step: Install HAProxy on Linux
Ubuntu/Debian
sudo apt update
sudo apt install -y haproxy
haproxy -v # verify version
RHEL/CentOS/AlmaLinux/Rocky
sudo dnf install -y haproxy
haproxy -v # verify version
Installing from official repos is sufficient for most use cases. For the latest features, consider the HAProxy Enterprise or community PPA/source builds, but stick to your organization’s patching policy.
Create a Basic HAProxy Configuration
We’ll build a clean haproxy.cfg with global and defaults sections, an HTTP frontend, and a backend pool with health checks. Replace IPs, domains, and health endpoints as needed.
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
sudo nano /etc/haproxy/haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
user haproxy
group haproxy
daemon
maxconn 4096
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 30s
timeout server 30s
retries 3
frontend http_in
bind *:80
option http-server-close
default_backend app_backend
backend app_backend
balance roundrobin
option httpchk GET /health
http-check expect status 200
server app1 10.0.0.10:80 check
server app2 10.0.0.11:80 check
This configuration distributes HTTP requests across two servers using round-robin and marks unhealthy instances “down”. Make sure your application exposes a lightweight /health endpoint that returns HTTP 200.
Start, Enable, and Open Firewall
# Validate config
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
# Start and enable
sudo systemctl enable --now haproxy
# Ubuntu/Debian with UFW
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# RHEL/CentOS family with firewalld
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Visit http://YOUR_DOMAIN or http://YOUR_IP to confirm traffic is reaching your backend servers. Tail logs to verify requests and health checks.
journalctl -u haproxy -f
Add HTTPS: SSL/TLS Termination with Let’s Encrypt
Terminate SSL at HAProxy to offload crypto from your app servers. We’ll obtain a certificate with Certbot, combine cert and key into a PEM, and configure a 301 redirect from HTTP to HTTPS.
1) Get a Let’s Encrypt Certificate
Point your domain’s A record to the HAProxy server. Temporarily stop HAProxy on port 80, then run Certbot in standalone mode.
sudo systemctl stop haproxy
sudo apt install -y certbot || sudo dnf install -y certbot
sudo certbot certonly --standalone -d example.com -d www.example.com
# Certificates will be under /etc/letsencrypt/live/example.com/
2) Create a PEM Bundle for HAProxy
sudo mkdir -p /etc/haproxy/certs
DOMAIN=example.com
sudo bash -c 'cat /etc/letsencrypt/live/'"$DOMAIN"'/fullchain.pem /etc/letsencrypt/live/'"$DOMAIN"'/privkey.pem > /etc/haproxy/certs/'"$DOMAIN"'.pem'
sudo chmod 600 /etc/haproxy/certs/"$DOMAIN".pem
3) Update haproxy.cfg for HTTPS and Redirect
frontend http_in
bind *:80
http-request redirect scheme https code 301 unless { ssl_fc }
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem alpn h2,http/1.1
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
default_backend app_backend
# Restart HAProxy
sudo systemctl start haproxy
sudo systemctl reload haproxy
Automate certificate renewals with a post-renewal hook that rebuilds the PEM and reloads HAProxy.
# /etc/letsencrypt/renewal-hooks/deploy/haproxy-renew.sh
#!/usr/bin/env bash
DOMAIN=example.com
cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/certs/$DOMAIN.pem
chmod 600 /etc/haproxy/certs/$DOMAIN.pem
systemctl reload haproxy
# Make executable
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/haproxy-renew.sh
Useful Production Features (Optional)
Sticky Sessions (Session Persistence)
Keep a client bound to the same server (helpful for stateful apps).
backend app_backend
balance roundrobin
cookie SRV insert indirect nocache
option httpchk GET /health
server app1 10.0.0.10:80 check cookie s1
server app2 10.0.0.11:80 check cookie s2
Path/Host-Based Routing with ACLs
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
acl host_api hdr(host) -i api.example.com
acl path_admin path_beg -i /admin
use_backend api_backend if host_api
http-request deny if path_admin !{ src 192.168.1.0/24 }
default_backend app_backend
backend api_backend
balance leastconn
server api1 10.0.0.20:8080 check
server api2 10.0.0.21:8080 check
Rate Limiting and Basic DDoS Guard
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
stick-table type ip size 100k expire 10m store http_req_rate(10s)
http-request track-sc0 src
http-request deny status 429 if { sc_http_req_rate(0) gt 100 }
default_backend app_backend
Stats and Health Visibility
listen stats
bind :8404
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:StrongPasswordHere
Visit http://YOUR_DOMAIN:8404/stats to view connections, backend states, and health.
Testing and Verification
- Connectivity: curl -I http://YOUR_DOMAIN and curl -I https://YOUR_DOMAIN
- Routing: Shut down app1 to confirm failover to app2
- Health checks: Watch journalctl -u haproxy -f for server UP/DOWN
- SSL: Qualify with an SSL scanner (A+ target) and confirm HSTS header
- Performance: ApacheBench, wrk, or k6 on a staging environment
Common Pitfalls and Fixes
- Port in use: Another service may hold 80/443. Run sudo ss -ltnp | grep -E ‘:80|:443’ and stop/disable the conflict.
- SELinux (RHEL-based): Allow outbound connections to any port with sudo setsebool -P haproxy_connect_any 1 or properly label ports with semanage.
- Firewall closed: Ensure ufw or firewalld allows http/https services.
- Bad health endpoint: Make /health fast, unauthenticated, and return 200 OK.
- Log visibility: If /var/log is empty, use journalctl, or enable rsyslog for local0/local1 if desired.
Performance Tuning Tips
- Right-size maxconn (global and per-frontend/backend) to match server resources.
- Use leastconn for uneven request times; roundrobin for uniform workloads.
- Enable HTTP/2 on TLS frontends with alpn h2,http/1.1 for better multiplexing.
- Keep timeouts realistic: too high piles up sockets, too low drops slow clients.
- Offload TLS at HAProxy and keep backend traffic over a private network.
When to Choose Managed HAProxy (Save Time)
If you prefer not to manage certificates, patches, and failover, a managed load balancer or a fully managed VPS can help. At YouStable, our engineers can provision HAProxy on performance-tuned VPS or cloud instances, set up SSL automation, and harden your stack—so you focus on your app, not the plumbing.
Frequently Asked Questions
How do I install and configure HAProxy on Ubuntu quickly?
Run sudo apt update && sudo apt install -y haproxy, then edit /etc/haproxy/haproxy.cfg to add a frontend on port 80 or 443 and a backend with your app servers. Validate with haproxy -c -f /etc/haproxy/haproxy.cfg, enable with systemctl enable –now haproxy, and open firewall ports.
What’s the difference between a reverse proxy and a load balancer in HAProxy?
As a reverse proxy, HAProxy sits in front of one application origin and handles TLS, caching (via backends/servers), and routing. As a load balancer, it distributes traffic across multiple origins, applying algorithms (roundrobin, leastconn), health checks, and failover. HAProxy can perform both roles simultaneously.
How do I enable sticky sessions in HAProxy?
Add cookie SRV insert in the backend and set a unique cookie per server (cookie s1, cookie s2). Browsers will send the cookie back and HAProxy will route to the same server, improving session persistence for stateful apps like older PHP or Java stacks.
Can HAProxy handle HTTPS with Let’s Encrypt automatically?
Yes, Use Certbot to obtain certificates and concatenate fullchain.pem + privkey.pem into a single .pem for HAProxy. Add a renewal hook to rebuild the PEM and reload HAProxy after certbot renew. This delivers near-hands-free SSL management.
How do I monitor HAProxy health and performance?
Enable the built-in stats page on a separate port, ship logs via journald/rsyslog, and integrate Prometheus/Grafana using an HAProxy exporter. Watch key metrics: backend up/down, response times, request rates, retries, and errors to catch issues early