bolt Valebyte VPS from $4/mo — NVMe, 60s deploy.

Get a VPS arrow_forward
eco Beginner Tutorial/How-to

HAProxy Configuration on VPS: High

calendar_month Jul 05, 2026 schedule 23 min read visibility 25 views
info

Need a server for this guide? We offer dedicated servers and VPS in 50+ countries with instant setup.

Need a server for this guide?

Deploy a VPS or dedicated server in minutes.

HAProxy Setup on VPS: High-Performance Load Balancing and Fault Tolerance

TL;DR

In this detailed guide, we will set up HAProxy on a VPS for efficient load balancing across multiple backend servers, ensuring high availability and fault tolerance for your web applications. You will learn how to install and configure HAProxy for HTTP and HTTPS traffic, add SSL termination, set up backend health checks and monitoring, and implement basic security measures and backups.

  • Install and configure HAProxy to distribute incoming traffic.
  • Set up HTTP and HTTPS load balancing with SSL termination on HAProxy.
  • Ensure fault tolerance using backend server health checks.
  • Implement basic security measures and HAProxy status monitoring.
  • Review configuration backup and maintenance strategies.
  • Gain practical experience deploying a highly available architecture on a VPS.

What we are setting up and why

In the modern world, the availability and performance of web services play a key role. A single server, no matter how powerful, is always a single point of failure. If it fails, your entire service becomes unavailable. Furthermore, with increasing load, a single server may not be able to handle the volume of requests, leading to slowdowns or complete failure.

Load balancing solves precisely these problems. We will be setting up HAProxy — a high-performance, reliable, and widely used open-source load balancer. HAProxy is capable of efficiently distributing incoming traffic among multiple backend servers. This not only improves performance by evenly distributing requests but also significantly enhances fault tolerance: if one of the backends fails, HAProxy automatically removes it from rotation and directs traffic to the remaining operational servers.

As a result of this tutorial, you will have a fully functional system where HAProxy acts as a "gatekeeper" in front of your applications. It will accept all incoming requests, terminate SSL (which offloads this burden from the backends), check the health of your actual servers, and direct requests only to those that are working correctly. This will allow you to easily scale your application by adding new backends as needed, and ensure continuous service operation even with partial failures.

Alternatives: Cloud-managed vs. Self-hosted on VPS

When it comes to load balancing, there are two main approaches: using managed cloud services (e.g., AWS ELB, Google Cloud Load Balancer, Azure Load Balancer) or self-hosting on your own VPS/dedicated server.

Cloud-managed load balancers offer convenience, automatic scaling, and deep integration with other cloud services. You don't need to worry about infrastructure management, updates, or the high availability of the load balancer itself — all of this is handled by the provider. However, this convenience comes at a cost, and the price of such solutions can be significantly higher, especially for projects with moderate loads or fixed budgets. Additionally, you are tied to the ecosystem of a specific cloud provider.

A Self-hosted load balancer on a VPS, such as HAProxy, gives you full control over configuration, optimization, and security. It is a significantly more economical solution, especially if you already have several VPS instances for backends. You can precisely configure HAProxy to your unique requirements, using advanced features that may be unavailable or expensive in cloud counterparts. This approach is ideal for those who want to maximize resource utilization, have server administration experience, or wish to avoid vendor lock-in. Setting up HAProxy on a VPS allows you to create a reliable and high-performance architecture that often surpasses cloud solutions in flexibility and cost for many tasks.

What VPS configuration is needed for this task

Choosing the right VPS for HAProxy depends on the expected load, the number of backend servers, and the type of traffic (HTTP/HTTPS). HAProxy itself is very lightweight and efficient, but when handling a large number of connections, especially with SSL termination, it will require more resources.

Minimum requirements for HAProxy (single instance):

  • CPU: 1 core. HAProxy utilizes a single core efficiently, but for high load or SSL termination, 2 cores might be beneficial.
  • RAM: 512 MB - 1 GB. HAProxy itself needs little memory, but the operating system and caches can use more. If you plan to terminate SSL, 1 GB will be more comfortable.
  • Disk: 20 GB SSD. HAProxy uses almost no disk space, but this will be sufficient for the OS, logs, and potential configuration backups. SSD is important for fast booting and file operations.
  • Network: 100 Mbps - 1 Gbps. Network bandwidth is a critical factor for a load balancer. Ensure your VPS has sufficient network capacity.

Recommended VPS plan for HAProxy (relevant for 2026):

For most medium-sized projects where HAProxy will handle up to several thousand concurrent connections and terminate SSL, the following configuration is recommended:

  • CPU: 2 cores (e.g., Intel Xeon E5 or AMD EPYC)
  • RAM: 2 GB
  • Disk: 40 GB NVMe SSD (for maximum disk operation performance)
  • Network: 1 Gbps port with guaranteed bandwidth of 200-500 Mbps.

Such a configuration will be sufficient to handle a significant volume of traffic and ensure stable operation. You can consider a VPS with the specified characteristics to rent a suitable server.

When a dedicated server is needed, not a VPS

A dedicated server becomes necessary when:

  • Extremely high load: If you expect tens or hundreds of thousands of concurrent connections, and your HAProxy becomes a bottleneck due to virtualization limitations.
  • Performance requirements: For applications with very low latency or high traffic volume, where even small delays inherent in virtualization are unacceptable.
  • Specialized hardware: If you need specific hardware components (e.g., very fast NVMe RAID arrays, GPUs) or full control over the hardware.
  • Strict security/isolation requirements: For certain regulatory requirements or security policies where complete physical isolation is mandatory.

For HAProxy, which is very efficient on its own, a dedicated server is usually only needed in the most high-load scenarios when it becomes the sole entry point for a huge cluster of backends.

VPS Location: What it affects

The choice of geographical location for your HAProxy VPS is critically important and affects several factors:

  • Latency: Place HAProxy as close as possible to your target audience. The shorter the distance between the user and the load balancer, the lower the latency and faster the response.
  • Latency to backends: HAProxy should be located as close as possible to your backend servers to minimize latency when forwarding requests. Ideally, they should be in the same data center or region.
  • Geopolitical factors and legislation: In some cases, the choice of location may depend on data storage requirements, regulations, or political considerations.
  • Cost: VPS prices can vary depending on the region.

The optimal strategy is to place HAProxy in the same data center or region as your primary backend servers, and which is geographically close to the majority of your users.

Server Preparation

Before installing and configuring HAProxy, you need to perform basic server preparation. These steps will enhance security and ease of administration.

1. Connecting to the server

Connect to your new VPS via SSH as the root user (unless otherwise specified by your provider).


ssh root@YOUR_VPS_IP_ADDRESS

2. System Update

Always start by updating the package manager and installed packages to their latest versions to ensure stability and security. We will use Ubuntu 24.04 LTS as the basis for our tutorial (relevant for 2026).


sudo apt update             # Update package list
sudo apt upgrade -y         # Upgrade all installed packages
sudo apt autoremove -y      # Remove unused packages

3. Creating a new user with sudo privileges

Working as the root user is insecure. Create a new user and grant them sudo privileges.


adduser your_username     # Create a new user
usermod -aG sudo your_username # Add user to the sudo group

Now, exit the root session and log in as the new user:


exit                        # Exit root session
ssh your_username@YOUR_VPS_IP_ADDRESS # Log in as the new user

4. Configuring SSH keys (recommended)

For increased security and convenience, use SSH keys instead of passwords. If you haven't already, generate keys on your local machine and copy the public key to the VPS.


# On your local machine:
ssh-keygen -t rsa -b 4096   # Generate a key pair (if not already done)
ssh-copy-id your_username@YOUR_VPS_IP_ADDRESS # Copy public key to VPS

After successfully copying the keys, it is recommended to disable password authentication for root and, possibly, for all users, allowing only key-based authentication. Edit /etc/ssh/sshd_config:


sudo nano /etc/ssh/sshd_config

Find and change the following lines (or add them if missing):


# ...
PermitRootLogin no
PasswordAuthentication no
# ...

Save changes (Ctrl+O, Enter) and exit (Ctrl+X). Restart the SSH service:


sudo systemctl restart sshd

IMPORTANT: Make sure you can log in via SSH with the new user and key before closing the current session to avoid losing access to the server.

5. Firewall Configuration (UFW)

Set up a simple firewall UFW (Uncomplicated Firewall) to allow only necessary traffic. By default, we will allow SSH, HTTP, and HTTPS.


sudo apt install ufw -y     # Install UFW
sudo ufw allow OpenSSH      # Allow SSH connections
sudo ufw allow http         # Allow HTTP (port 80)
sudo ufw allow https        # Allow HTTPS (port 443)
sudo ufw enable             # Enable UFW
sudo ufw status verbose     # Check firewall status

HAProxy may also use additional ports for statistics or other purposes, which we will open later if needed.

6. Installing Fail2Ban (recommended)

Fail2Ban helps protect against brute-force attacks by automatically blocking IP addresses from which numerous failed login attempts originate.


sudo apt install fail2ban -y # Install Fail2Ban
sudo systemctl enable fail2ban # Enable Fail2Ban autostart
sudo systemctl start fail2ban  # Start Fail2Ban service
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local # Copy config for customization

Fail2Ban protects SSH by default. You can configure it to protect other services as needed.

Software Installation — Step-by-step

Software Installation — Step-by-Step

Now that the server is prepared, let's proceed with the installation of HAProxy and auxiliary components.

1. HAProxy Installation

HAProxy is available in the standard Ubuntu repositories. We will install the latest stable version available for Ubuntu 24.04 LTS, which will be supported and updated until 2026.


sudo apt install haproxy -y # Install HAProxy from repositories

Check the installed HAProxy version. Version 2.9 or higher is expected, as Ubuntu 24.04 LTS usually comes with up-to-date versions.


haproxy -v                  # Check HAProxy version

The output should be similar to this (version may vary but will be current):


HAProxy version 2.9.x-x ...

After installation, HAProxy will be started as a system service. Check its status:


sudo systemctl status haproxy # Check HAProxy service status

If it's not running, you can start it with the command:


sudo systemctl start haproxy  # Start HAProxy service
sudo systemctl enable haproxy # Enable autostart on system boot

2. Installation of Auxiliary Backend Servers (for testing)

To demonstrate load balancing, we will need at least two backend servers. We will install Nginx on two different ports on the same VPS to simulate two separate backends. In a real environment, these would be separate servers.


sudo apt install nginx -y   # Install Nginx, if not already installed

Let's create two separate Nginx configuration files so they listen on different ports. For simplicity, we will use ports 8080 and 8081.


sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/backend1.conf
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/backend2.conf

Edit /etc/nginx/sites-available/backend1.conf:


sudo nano /etc/nginx/sites-available/backend1.conf

Change the server block to:


server {
    listen 8080 default_server;
    listen [::]:8080 default_server;
    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;
    server_name _;
    location / {
        add_header X-Backend-Server "Backend 1";
        try_files $uri $uri/ =404;
    }
}

Edit /etc/nginx/sites-available/backend2.conf:


sudo nano /etc/nginx/sites-available/backend2.conf

Change the server block to:


server {
    listen 8081 default_server;
    listen [::]:8081 default_server;
    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;
    server_name _;
    location / {
        add_header X-Backend-Server "Backend 2";
        try_files $uri $uri/ =404;
    }
}

Create symbolic links to activate these configurations and remove the default one:


sudo rm /etc/nginx/sites-enabled/default # Remove default Nginx link
sudo ln -s /etc/nginx/sites-available/backend1.conf /etc/nginx/sites-enabled/backend1.conf
sudo ln -s /etc/nginx/sites-available/backend2.conf /etc/nginx/sites-enabled/backend2.conf

Check the Nginx configuration and restart it:


sudo nginx -t                 # Check Nginx configuration syntax
sudo systemctl restart nginx  # Restart Nginx

Now open ports 8080 and 8081 in UFW so HAProxy can access them (these ports will not be accessible externally, only for local HAProxy).


sudo ufw allow 8080/tcp       # Allow access to port 8080
sudo ufw allow 8081/tcp       # Allow access to port 8081
sudo ufw reload               # Reload UFW rules

In a real situation, backends will be on separate IP addresses, and you will only need to open ports 80 and 443 on HAProxy, and on the backends — ports for internal connections only from the HAProxy IP.

Configuration

The main HAProxy configuration file is located at /etc/haproxy/haproxy.cfg. Before making any changes, always back up the original file.


sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
sudo nano /etc/haproxy/haproxy.cfg

Clear the contents of the haproxy.cfg file and paste the following configuration. This config includes global settings, default settings, a frontend for HTTP and HTTPS, and a backend for our Nginx servers.

Example HAProxy Configuration for HTTP and HTTPS with SSL Termination

We will configure HAProxy to handle HTTP traffic (redirecting to HTTPS) and HTTPS traffic with SSL termination. For SSL certificates, we will use Let's Encrypt via Certbot.

Obtaining an SSL Certificate with Certbot

Before configuring HTTPS, we need an SSL certificate. Let's install Certbot and obtain a certificate for your domain (replace your_domain.com with your actual domain).


sudo apt install certbot -y   # Install Certbot
sudo certbot certonly --standalone -d your_domain.com -d www.your_domain.com --agree-tos --email [email protected] --non-interactive # Obtain certificate

Certbot defaults to using port 80 for standalone mode. Make sure port 80 is free when running this command (temporarily stop Nginx if it's already listening on 80).


sudo systemctl stop nginx # Temporarily stop Nginx if it's listening on 80
# ... run certbot command ...
sudo systemctl start nginx # Start Nginx back up

Certificates will be located in /etc/letsencrypt/live/your_domain.com/. HAProxy requires the certificate in PEM format, which combines the private key and the full certificate chain. Let's create such a file:


sudo mkdir -p /etc/haproxy/certs/
sudo cat /etc/letsencrypt/live/your_domain.com/fullchain.pem /etc/letsencrypt/live/your_domain.com/privkey.pem | sudo tee /etc/haproxy/certs/your_domain.com.pem > /dev/null
sudo chmod -R go-rwx /etc/haproxy/certs # Set strict permissions

Now HAProxy will be able to use this file /etc/haproxy/certs/your_domain.com.pem for SSL termination.

HAProxy Configuration File (/etc/haproxy/haproxy.cfg)

global
    log /dev/log    local0
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
    stats timeout 30s
    user haproxy
    group haproxy
    daemon
    # Updating HAProxy to version 2.9+ allows using more CPU cores
    # nbthread 2 # Uses 2 threads/CPU cores, if available
    cpu-map 1 0 # Bind thread 1 to core 0
    cpu-map 2 1 # Bind thread 2 to core 1 (if nbthread 2)
    maxconn 20000 # Maximum number of concurrent connections

defaults
    mode http
    log global
    option httplog
    option dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option redispatch
    retries 3
    timeout http-request 10s
    timeout queue 1m
    timeout connect 10s
    timeout client 1m
    timeout server 1m
    timeout http-keep-alive 20s
    timeout check 10s
    maxconn 5000 # Maximum number of connections per frontend/backend

# Frontend for HTTP traffic (redirect to HTTPS)
frontend http_in
    bind *:80
    mode http
    redirect scheme https code 301 if !{ ssl_fc } # Redirect all HTTP to HTTPS

# Frontend for HTTPS traffic with SSL termination
frontend https_in
    bind *:443 ssl crt /etc/haproxy/certs/your_domain.com.pem # Replace with your domain
    mode http
    option httplog
    # ACL to determine which backend to use
    acl url_static path_beg /static /images /css /js
    acl url_admin path_beg /admin
    # Using ACL to select backend
    use_backend bk_static if url_static
    use_backend bk_admin if url_admin
    default_backend bk_webservers

# Backend for static content (optional)
backend bk_static
    mode http
    balance roundrobin # Balancing method: round-robin
    server static_server 127.0.0.1:8082 check # Example static server, if any

# Backend for admin panel (optional)
backend bk_admin
    mode http
    balance leastconn # Balancing method: least connections
    server admin_server 127.0.0.1:8083 check # Example admin server

# Backend for main web servers
backend bk_webservers
    mode http
    balance roundrobin # Balancing method: round-robin
    option httpchk GET /healthz # Health check via URL /healthz
    # In a real environment, this will be the IP addresses and ports of your backend servers
    # For example: server web1 192.168.1.10:80 check
    #           server web2 192.168.1.11:80 check
    server web1 127.0.0.1:8080 check inter 2s fall 3 rise 2 weight 100
    server web2 127.0.0.1:8081 check inter 2s fall 3 rise 2 weight 100

# HAProxy Statistics
listen stats
    bind *:8000 # Port for HAProxy statistics access
    mode http
    stats enable
    stats uri /haproxy_stats # URL for statistics
    stats realm Haproxy\ Statistics # Authorization realm name
    stats auth admin:PASSWORD_HA_PROXY # Login and password for access (must change!)
    stats refresh 10s # Refresh statistics every 10 seconds

Important configuration notes:

  • Replace your_domain.com with your actual domain in the line bind *:443 ssl crt /etc/haproxy/certs/your_domain.com.pem.
  • Replace PASSWORD_HA_PROXY with a strong password for accessing the statistics page.
  • In the backend bk_webservers section:
    • balance roundrobin: A load balancing method that distributes requests in a round-robin fashion. Other popular methods: leastconn (least active connections), source (based on client IP address for "sticky" sessions).
    • option httpchk GET /healthz: HAProxy will send an HTTP GET request to the path /healthz on each backend to check its health. Your backends should respond to this URL with 200 OK.
    • server web1 127.0.0.1:8080 check inter 2s fall 3 rise 2 weight 100:
      • web1: Server name.
      • 127.0.0.1:8080: IP address and port of the backend. In a real environment, these will be the IP addresses of your other VPS instances.
      • check: Enables health checking.
      • inter 2s: Interval between health checks (2 seconds).
      • fall 3: The server will be considered unhealthy after 3 failed checks.
      • rise 2: The server will be considered healthy after 2 successful checks.
      • weight 100: Relative weight of the server in load balancing (higher weight means it receives more traffic).

HAProxy Configuration Check

Always check the configuration syntax before restarting HAProxy.


sudo haproxy -c -f /etc/haproxy/haproxy.cfg # Check config syntax

If there are no errors, you will see the message "Configuration file is valid". Now restart HAProxy:


sudo systemctl restart haproxy # Restart HAProxy service
sudo systemctl status haproxy  # Check status

Configuring Nginx for /healthz

For HAProxy to be able to check the health of our backends, Nginx must respond to /healthz. Add the following location block inside the server block in each Nginx configuration file (/etc/nginx/sites-available/backend1.conf and backend2.conf):


location /healthz {
    return 200 'OK';
    add_header Content-Type text/plain;
}

After modifying each Nginx file, check and restart Nginx:


sudo nginx -t
sudo systemctl restart nginx

Verifying Functionality

1. HTTP/HTTPS Access

Open your domain (your_domain.com) in a browser. You should be automatically redirected to HTTPS, and the content should load. If you refresh the page several times, you will see the X-Backend-Server change between "Backend 1" and "Backend 2", confirming that load balancing is working.


curl -I http://your_domain.com # Check redirect
curl -I https://your_domain.com # Check HTTPS and backend header
2. HAProxy Statistics Access

Open http://YOUR_VPS_IP_ADDRESS:8000/haproxy_stats in your browser. Enter the login admin and the password you set in the config. You will see the statistics page, which will display the status of your backends, the number of connections, and other metrics. This is an excellent tool for monitoring.

Backups and Maintenance

A reliable backup system and regular maintenance are critically important for any production environment.

What to Back Up

For HAProxy, the main elements to back up are:

  • HAProxy Configuration Files: /etc/haproxy/haproxy.cfg and any other files it references (e.g., ACL lists if they are in separate files).
  • SSL Certificates: The directory /etc/letsencrypt/live/your_domain.com/ and the combined PEM file /etc/haproxy/certs/your_domain.com.pem. These files contain private keys and must be stored securely.

Simple Auto-Backup Script

Let's create a simple script that will archive important files and send them to a secure location. As an example, we will use rsync to copy to a remote server or S3-compatible storage (e.g., MinIO, Wasabi, or another VPS). For S3-compatible storage, you will need to install awscli or another S3 client.

Assume you have a remote backup server with user backupuser and a configured SSH key.


sudo nano /usr/local/bin/backup_haproxy.sh

Script content (replace backupuser@backup_server_ip and /path/to/remote/backups):


#!/bin/bash

# Temporary backup directory
BACKUP_DIR="/tmp/haproxy_backup"
DATE=$(date +%Y%m%d%H%M%S)
ARCHIVE_NAME="haproxy_config_${DATE}.tar.gz"
REMOTE_DEST="backupuser@backup_server_ip:/path/to/remote/backups" # Replace with your remote server

mkdir -p "$BACKUP_DIR"

echo "Starting HAProxy configuration and SSL certificate backup..."

# Copy HAProxy configs
cp /etc/haproxy/haproxy.cfg "$BACKUP_DIR/"
cp -R /etc/haproxy/certs "$BACKUP_DIR/" # Copy combined PEM file
# Copy original Let's Encrypt certificates
cp -R /etc/letsencrypt/live/your_domain.com "$BACKUP_DIR/letsencrypt_certs" # Replace with your domain

# Create archive
tar -czf "$BACKUP_DIR/$ARCHIVE_NAME" -C "$BACKUP_DIR" .

echo "Archive created: $BACKUP_DIR/$ARCHIVE_NAME"

# Send archive to remote server
if rsync -avz "$BACKUP_DIR/$ARCHIVE_NAME" "$REMOTE_DEST"; then
    echo "Backup successfully sent to $REMOTE_DEST"
else
    echo "Error sending backup to $REMOTE_DEST"
    exit 1
fi

# Clean up temporary files
rm -rf "$BACKUP_DIR"

echo "Backup completed."

Make the script executable:


sudo chmod +x /usr/local/bin/backup_haproxy.sh

Setting Up Cron for Automatic Execution

Add the script to Cron for daily or weekly execution.


sudo crontab -e

Add the following line for daily execution at 3:00 AM:


0 3 * * * /usr/local/bin/backup_haproxy.sh > /var/log/haproxy_backup.log 2>&1

Where to Store Backups

  • External S3-compatible service: Cloud storage like Amazon S3, DigitalOcean Spaces, Backblaze B2, MinIO (self-hosted) — this is a reliable and scalable option.
  • Separate VPS: You can use another, less powerful VPS specifically for storing backups.
  • NAS/Local Storage: For home use or small businesses.

The main rule: backups must be stored separately from the main server, preferably in a different geographical location.

Updates: Rolling vs. Maintenance Window

Regular software updates are important for security and new features. For HAProxy, there are several approaches:

  • Maintenance Window: A traditional approach where updates are applied at a predetermined time when traffic is minimal. This can lead to brief downtime but is simpler to implement for a single HAProxy instance. For this, it's sufficient to run sudo apt update && sudo apt upgrade -y and restart HAProxy.
  • Rolling Updates: For high-availability systems with two or more HAProxy instances. Update one load balancer at a time. First, update one, redirect all traffic to it, then update the second. This ensures zero downtime but requires a more complex architecture with multiple HAProxy instances (e.g., using Keepalived for VIP).

For a single VPS with HAProxy, as in this tutorial, the maintenance window approach is the most practical. Always ensure you check the HAProxy configuration (haproxy -c) after any changes or updates before restarting the service.

Renewing Let's Encrypt Certificates

Certbot automatically sets up a cron job for certificate renewal. You can check this:


sudo systemctl list-timers | grep certbot

If the certificates are successfully renewed, you will need to combine them again into a PEM file for HAProxy and reload HAProxy:


# This script can be added to cron after Certbot's automatic renewal
#!/bin/bash
DOMAIN="your_domain.com" # Replace with your domain
CERT_PATH="/etc/letsencrypt/live/$DOMAIN"
HAPROXY_CERT_PATH="/etc/haproxy/certs/$DOMAIN.pem"

if [ -f "$CERT_PATH/fullchain.pem" ] && [ -f "$CERT_PATH/privkey.pem" ]; then
    sudo cat "$CERT_PATH/fullchain.pem" "$CERT_PATH/privkey.pem" | sudo tee "$HAPROXY_CERT_PATH" > /dev/null
    sudo chmod -R go-rwx /etc/haproxy/certs
    sudo systemctl reload haproxy
    echo "HAProxy SSL certificate updated and HAProxy reloaded."
else
    echo "Error: Let's Encrypt certificates not found for $DOMAIN."
fi

Save this script, for example, as /usr/local/bin/renew_haproxy_cert.sh, make it executable, and add it to cron to run after Certbot's renewal (e.g., weekly).

Troubleshooting + FAQ

In this section, we will cover common issues you might encounter when configuring HAProxy and provide answers to frequently asked questions.

HAProxy Does Not Start or Shows a Configuration Error

Problem: After changing haproxy.cfg, HAProxy does not start, or systemctl status haproxy shows errors.

What to check:

  • Configuration Syntax: This is the most common cause. Use sudo haproxy -c -f /etc/haproxy/haproxy.cfg to check the syntax. Any typo or incorrect indentation can lead to an error.
  • HAProxy Logs: Check system logs: sudo journalctl -u haproxy or sudo tail -f /var/log/syslog. HAProxy usually describes the reason for failure in great detail.
  • Port Availability: Ensure that the ports HAProxy is trying to listen on (e.g., 80, 443) are not occupied by another process (e.g., Nginx). Use sudo ss -tulpn | grep -E "80|443".
  • File Permissions: Ensure that the haproxy user (or whichever user it runs under) has read permissions for the configuration file and SSL certificates.

How to fix: Correct errors in haproxy.cfg, free up occupied ports, check permissions. After every HAProxy configuration change, run sudo haproxy -c -f /etc/haproxy/haproxy.cfg and only then sudo systemctl restart haproxy.

Error "503 Service Unavailable" or "No servers are available"

Problem: The browser shows a 503 error, or HAProxy logs indicate that backends are unavailable.

What to check:

  • Backend Status: Check if your backend servers (Nginx, Apache, your application) are running and listening on the correct ports. Use sudo systemctl status nginx (or your application).
  • Backend Accessibility from HAProxy: From the HAProxy server, try connecting to the backend directly: curl http://127.0.0.1:8080/healthz (replace IP and port with actual backends). Ensure that the firewall on the backends (if they are on other VPS) allows incoming connections from the HAProxy IP address.
  • Health Check Settings: Ensure that option httpchk and the path /healthz are configured correctly in both HAProxy and on the backends.
  • HAProxy Statistics Page: Open the HAProxy statistics page (http://YOUR_VPS_IP_ADDRESS:8000/haproxy_stats) and check the status of the backend servers. It will indicate the reason why servers are marked as DOWN.

How to fix: Resolve issues on the backends, check network connectivity, adjust health check settings. If backends are on separate VPS instances, ensure their firewalls allow incoming connections from HAProxy.

Slow Performance or High Latency

Problem: The application runs slowly, or requests are processed with high latency when passing through HAProxy.

What to check:

  • HAProxy Load: Check CPU and RAM usage on the VPS running HAProxy (htop, top). High CPU load can indicate a bottleneck, especially with intensive SSL termination.
  • Network Bandwidth: Ensure that the network is not a bottleneck. Use iftop or nload.
  • HAProxy Timeouts: Check timeout client, timeout server, timeout connect settings in haproxy.cfg. Too short timeouts can interrupt slow connections.
  • Backend Load: Check the load on the backend servers themselves. The problem might not be with HAProxy, but with insufficient resources on the backends or an unoptimized application.

How to fix: Increase VPS resources for HAProxy (CPU/RAM) if it is overloaded. Optimize timeout settings. Consider adding more backend servers or optimizing your application.

Incorrect Client IP Address in Backend Logs

Problem: Your backend server logs (Nginx, Apache) show the HAProxy IP address instead of the real client IP address.

What to check: Ensure that the option forwardfor is enabled in the defaults or frontend section of HAProxy. HAProxy adds the X-Forwarded-For header with the real client IP.

How to fix: Configure your backend server to read the X-Forwarded-For header. For example, for Nginx, add to the log_format block:


log_format combined_proxy '$remote_addr - $remote_user [$time_local] '
                          '"$request" $status $body_bytes_sent '
                          '"$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log combined_proxy;

Or use the real_ip module if HAProxy is in your internal network.

SSL Certificates Not Working or Expired

Problem: Browsers show security warnings, or HTTPS is not working.

What to check:

  • Certificate Expiration: Check the certificate's expiration date: sudo openssl x509 -in /etc/haproxy/certs/your_domain.com.pem -noout -dates.
  • Certificate Path: Ensure that the path to the PEM file in haproxy.cfg (bind *:443 ssl crt /etc/haproxy/certs/your_domain.com.pem) is correct.
  • Certificate Format: HAProxy requires a combined PEM file. Ensure that you have correctly combined fullchain.pem and privkey.pem.
  • Automatic Renewal: Check if the Certbot cron job for certificate renewal and your script for updating the HAProxy PEM file are working.

How to fix: Renew the certificate using Certbot (sudo certbot renew --force-renewal if urgent). Correct file paths or format. Ensure that the HAProxy certificate update script runs after Certbot's renewal.

What is the minimum suitable VPS configuration?

For HAProxy acting as a load balancer for a small to medium project (up to several hundred concurrent connections), a VPS with 1 CPU core, 1 GB RAM, 20-40 GB SSD, and a network channel of at least 100 Mbps will be minimally suitable. If intensive SSL termination or very high traffic is planned, it is recommended to increase the CPU to 2 cores and RAM to 2 GB. It is also important to ensure that the backend servers to which HAProxy will forward traffic have sufficient resources.

What to choose — VPS or dedicated for this task?

The choice between a VPS and a dedicated server for HAProxy depends on the scale and criticality of your project. For most web applications and services, even with thousands of concurrent users, a powerful VPS will be more than sufficient. HAProxy is very efficient and can handle a significant amount of traffic on a virtual machine. A dedicated server should only be considered in cases of extreme load (tens and hundreds of thousands of concurrent connections), when VPS CPU performance or network bandwidth becomes a bottleneck due to virtualization limitations, or when full control over hardware and maximum physical isolation are required. To start, it is always recommended to begin with a well-configured VPS and then scale up to a dedicated server if truly necessary.

Conclusions and Next Steps

Congratulations! You have successfully configured HAProxy on your VPS, creating a high-performance and fault-tolerant architecture for your web applications. Now your service can efficiently distribute load among multiple backend servers, terminate SSL traffic, and automatically handle failures of individual components, significantly increasing availability and stability.

Next steps for developing your infrastructure:

  • Adding a second HAProxy with Keepalived: To ensure full fault tolerance of the load balancer itself, deploy a second HAProxy instance and use Keepalived to create a Virtual IP (VIP) that will automatically switch between active and passive HAProxy in case of failure.
  • Monitoring and Alerts: Integrate HAProxy with monitoring systems such as Prometheus + Grafana, Zabbix, or Datadog. This will allow you to track key metrics (number of connections, backend status, latencies) and receive alerts about any anomalies.
  • Deployment Automation: To simplify management and scaling, consider using configuration automation tools such as Ansible, Puppet, or Chef for deploying and managing HAProxy and backend servers.
  • Advanced HAProxy Features: Explore more advanced HAProxy features such as caching, URL rewriting, DDoS attack protection, integration with WAF (Web Application Firewall), and dynamic configuration changes without restarting.

Was this guide helpful?

HAProxy setup on VPS: high-performance load balancing and fault tolerance
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.