HAProxy can update its configuration on the fly without dropping a single connection.
Let’s say you’ve got a running HAProxy instance serving traffic, and you need to add a new backend server, or perhaps change a health check timeout. Normally, this would require restarting HAProxy, which means a brief interruption of service. The Data Plane API (DPAPI) lets you avoid that.
Here’s HAProxy serving two backend servers, web-01 and web-02, both listening on port 8080.
frontend http_frontend
bind *:80
default_backend http_backend
backend http_backend
balance roundrobin
server web-01 192.168.1.10:8080 check
server web-02 192.168.1.11:8080 check
Now, imagine we want to add a third server, web-03 at 192.168.1.12:8080.
First, you need to enable the DPAPI in your HAProxy configuration. This typically involves adding a stats socket line that also exposes the DPAPI.
global
stats socket 127.0.0.1:9999 mode 660 level admin expose-fd listeners
stats timeout 2m
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http_frontend
bind *:80
default_backend http_backend
backend http_backend
balance roundrobin
server web-01 192.168.1.10:8080 check
server web-02 192.168.1.11:8080 check
The stats socket directive creates a Unix domain socket or TCP socket that HAProxy listens on. The expose-fd listeners part is crucial for DPAPI functionality, allowing it to manage HAProxy’s file descriptors.
Once HAProxy is reloaded with this configuration, you can interact with the DPAPI. You’ll need a client, and curl is a common choice. The DPAPI communicates over HTTP, typically on port 127.0.0.1:12345 or a similar port you configure. For this example, let’s assume it’s running on 127.0.0.1:12345.
To add the new server, you’d send a POST request to the /services/haproxy/runtime/servers endpoint. You need to specify the HAProxy service name (usually haproxy), the backend name, and the server details.
curl -X POST "http://127.0.0.1:12345/services/haproxy/runtime/servers?service=haproxy&backend=http_backend" \
-H "Content-Type: application/json" \
-d '{
"name": "web-03",
"address": "192.168.1.12:8080",
"check": "enabled"
}'
This request tells HAProxy to add a server named web-03 at 192.168.1.12:8080 and enable its health checks. HAProxy will immediately start health checking this new server and, if it’s healthy, begin sending traffic to it according to the balance roundrobin policy. No restart, no downtime.
You can also modify existing servers. For instance, to disable health checks for web-02:
curl -X PUT "http://127.0.0.1:12345/services/haproxy/runtime/servers/web-02?service=haproxy&backend=http_backend" \
-H "Content-Type: application/json" \
-d '{
"check": "disabled"
}'
Or to remove it entirely:
curl -X DELETE "http://127.0.0.1:12345/services/haproxy/runtime/servers/web-02?service=haproxy&backend=http_backend"
The DPAPI isn’t just for servers; it can manage ACLs, listen ports, and much more. It fundamentally works by communicating with the HAProxy master process through the stats socket, sending commands that the master process then applies to its running configuration without needing to re-read the entire haproxy.cfg file. This is why it’s so fast and non-disruptive.
The most surprising thing about the DPAPI is how granular its control is. You can enable or disable individual server instances, change their weight, or even modify complex ACL rules in real-time, all without affecting ongoing connections. This fine-grained control is managed through JSON payloads sent to specific API endpoints that map directly to HAProxy’s internal configuration objects.
You can inspect the current configuration state by making GET requests. For example, to see all servers in the http_backend:
curl "http://127.0.0.1:12345/services/haproxy/runtime/servers?service=haproxy&backend=http_backend"
This allows for dynamic, automated management of your HAProxy load balancing setup, crucial for modern, elastic infrastructures.
The next logical step is to explore how to automate these DPAPI calls using tools like Ansible or Terraform, or to integrate them into your CI/CD pipelines for zero-downtime deployments.