Back to articles
Technology Insight

High Availability on Budget Hardware: Configuring Keepalived and HAProxy for Floating IPs on Hetzner Cloud VPS

June 2, 2026

Introduction: The Challenge of High Availability on Standard Cloud VPS

In modern cloud architecture, achieving high availability (HA) is no longer a luxury—it is a core business requirement. A single point of failure (SPOF) in your infrastructure can lead to costly downtime, damaged reputation, and lost revenue. Typically, enterprise cloud providers offer built-in, hardware-level redundant load balancers that automatically handle traffic failover via a Virtual IP (VIP) or Floating IP. However, cost-effective infrastructure providers, like Hetzner Cloud in certain standard VPS configurations, do not always provide automated layer-2 hardware-assisted IP failover natively out of the box without additional subscription costs or complex setups.

Fortunately, you can achieve enterprise-grade resilience using open-source tools. This technical guide will demonstrate how to configure Keepalived and HAProxy on two standard Hetzner VPS instances to create a self-healing, high-availability cluster using a software-driven Floating IP. By the end of this tutorial, your infrastructure will be capable of detecting a node failure and shifting traffic seamlessly in milliseconds.

Understanding the Architecture: Keepalived and HAProxy

Before diving into the configuration, it is essential to understand the roles of the two primary software components in our high-availability stack:

  • HAProxy (High Availability Proxy): A high-performance, open-source load balancer and proxy server for TCP and HTTP-based applications. It distributes incoming traffic across multiple backend application servers, ensuring optimal resource utilization and traffic management.
  • Keepalived: A routing software based on the Virtual Router Redundancy Protocol (VRRP). Keepalived is responsible for monitoring the health of the nodes and managing the dynamic allocation of the Floating IP. If the primary node goes offline, Keepalived automatically migrates the IP address to the secondary node.

In our architecture, we will utilize two Hetzner Cloud VPS instances, which we will refer to as Node 1 (Primary/Master) and Node 2 (Secondary/Backup). Both nodes will run an instance of HAProxy and Keepalived. The Floating IP will actively route traffic to Node 1. If Node 1 fails, Keepalived will shift the Floating IP to Node 2 instantly.

Prerequisites and Environment Setup

To follow along with this guide, ensure you have the following prerequisites ready:

  1. Two Ubuntu 22.04 or 24.04 LTS VPS instances hosted on Hetzner Cloud.
  2. A Failover IP (Floating IP) purchased and assigned to your account within the same Hetzner project/network zone.
  3. Root or sudo access to both servers.
  4. Internal private networking enabled between both nodes (e.g., 10.0.0.11 for Node 1 and 10.0.0.12 for Node 2).
Note: Because Hetzner's network environment is routed (Layer 3) rather than switched (Layer 2), standard VRRP broadcast messages used by Keepalived cannot traverse the public network directly. We will overcome this limitation by using unicast communication over a Hetzner Private Network or using Hetzner's API to reassign the IP. This guide focuses on the robust Unicast Private Network method.

Step 1: Installing Keepalived and HAProxy

First, we must update our system repositories and install the required software packages on both Node 1 and Node 2. Execute the following commands on both servers:

sudo apt update
sudo apt install -y keepalived haproxy

Once installed, stop the services temporarily so we can configure them from scratch:

sudo systemctl stop keepalived
sudo systemctl stop haproxy

Step 2: Configuring HAProxy for Load Balancing

Next, we need to configure HAProxy to handle the incoming traffic. The configuration should be identical on both servers, ensuring that whichever node holds the Floating IP can process requests optimally.

Open the HAProxy configuration file on both nodes:

sudo nano /etc/haproxy/haproxy.cfg

Append the following configuration block to the end of the file. This configuration sets up a frontend listening on port 80 and shifts traffic to backend application servers (replace the backend IPs with your actual application or web server IPs):

frontend http_front
    bind *:80
    stats uri /haproxy?stats
    default_backend http_back

backend http_back
    balance roundrobin
    server app_server1 10.0.0.21:80 check
    server app_server2 10.0.0.22:80 checkSave and close the file. To allow HAProxy to bind to the Floating IP address (which may not always be assigned to the local network interface), we must enable non-local binding in the Linux kernel configuration. Run the following command on both servers:

echo "net.ipv4.ip_nonlocal_bind=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Step 3: Configuring Keepalived with Unicast VRRP

Now, we will configure Keepalived. This is where the configuration diverges between the Master and Backup nodes. We will configure Keepalived to communicate via unicast over the Hetzner Private Network interface (e.g., enp7s0 or similar; verify your interface name using ip a).

On Node 1 (Master Server)

Create or overwrite the configuration file:

sudo nano /etc/keepalived/keepalived.conf

Insert the following configuration:

vrrp_script check_haproxy {
    script "/usr/bin/killall -0 haproxy"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state MASTER
    interface enp7s0
    virtual_router_id 51
    priority 101
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass SecureSecret123
    }

    unicast_src_ip 10.0.0.11
    unicast_peer {
        10.0.0.12
    }

    virtual_ipaddress {
        /32
    }

    track_script {
        check_haproxy
    }
}

On Node 2 (Backup Server)

Create the configuration file on the second node:

sudo nano /etc/keepalived/keepalived.conf

Insert the backup configuration, noting the lower priority value and reversed unicast IPs:

vrrp_script check_haproxy {
    script "/usr/bin/killall -0 haproxy"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface enp7s0
    virtual_router_id 51
    priority 100
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass SecureSecret123
    }

    unicast_src_ip 10.0.0.12
    unicast_peer {
        10.0.0.11
    }

    virtual_ipaddress {
        /32
    }

    track_script {
        check_haproxy
    }
}

Step 4: Integrating with Hetzner API (Failover Script)

Because Hetzner Cloud infrastructure requires a control-plane API call to re-route a Floating IP to a new MAC address, relying purely on standard VRRP packets inside a private network isn't always enough to update Hetzner's external routing tables. We need a script that calls the Hetzner API during a failover event.

Create a script called /etc/keepalived/failover.sh on both nodes:

sudo nano /etc/keepalived/failover.sh

Add a curl command that updates the Floating IP assignment via the Hetzner Cloud API using your API token and server ID. (For production, implement a Python or Bash script that triggers on Keepalived's notify_master state change).

Once all configurations are updated, start and enable the services on both nodes:

sudo systemctl enable --now haproxy
sudo systemctl enable --now keepalived

Step 5: Testing and Verification

To verify that your high-availability configuration is operating correctly, run the following command on Node 1:

ip addr show enp7s0

You should see your Hetzner Floating IP bound to the interface. Now, simulate a critical failure on Node 1 by stopping the HAProxy or Keepalived service:

sudo systemctl stop keepalived

Check the network interface on Node 2. Within milliseconds, Node 2 should assume the MASTER role, and the Floating IP will seamlessly appear on Node 2's network interface. Your applications remain online, and your business avoids downtime.

Conclusion

Building high-availability clusters does not require expensive hardware contracts or enterprise cloud tiers. By leveraging Keepalived for intelligent health checking and HAProxy for robust load balancing, you can deploy a reliable, production-ready infrastructure on budget-friendly Hetzner Cloud VPS instances. Implementing this architecture protects your operations from hardware anomalies, network degradation, and localized software failures, delivering enterprise-level uptime to your end-users.

High Availability on Budget Hardware: Configuring Keepalived and HAProxy for Floating IPs on Hetzner Cloud VPS | DPTCloud