How to Setup HAProxy in Ubuntu 16.04

HAProxy is an open-source high availability load balancing and proxy services tools for TCP and HTTP-based network applications. It is easy to use, suits for high volume websites and  its seamless integration into  existing architectures. It offers transparent connections, server offloading, enforcement of policies, limit connections apart from its primary function of proxy service. In this article we explain how to setup haproxy in Ubuntu 16.04.

1. Setup Network

We will add three web-server running with Apache2 and one HAPROXY server that will proxy all request/response of the three web service in our network.

The following lists Web Server Details in our network.

Server 1:    site1.local
Server 2:    site2.local
Server 3:    site3.local

HAProxy Server:


We will also attach one public IP to  load-balancer.local so as to access it  from public domain (optional). If you don't wish to access it from public domain, then you can skip attaching the public IP assuming you will access the proxy server within your network.

2. Configure hostname

Since we are going to access the load balancer and web server by their name ( not by IPADDRESS ) therefore we will setup the hostname of three web-server and one proxy server. We will setup hostname of three web-servers and proxy server as site1.local, site2.local, site3.local and load-balancer.local respectively.

We will setup hostname of as site1.local in /etc/hosts and /etc/hostname

root@site1:~# vi /etc/hosts localhost site1.local

root@site1:~# vi /etc/hostname

Restart network

root@site1:~#  service networking restart

Install apache and enable it.

root@site1:~# apt-get install apache2

root@site1:~# service apache2 enable

root@site1:~# service apache2 start

Create an index file for site1.local

root@site1:~# vi /var/www/html/index.html

<html xmlns="">
<h1> Hi, This is </h1>

Add firewall rule for http

# ufw allow 80/tcp
# ufw reload

Now check whether you can access site1

root@site1:~# curl -I site1.local
HTTP/1.1 200 OK
Date: Sun, 14 Aug 2016 14:30:29 GMT
Server: Apache/2.4.18 (Ubuntu)
Last-Modified: Sun, 14 Aug 2016 03:50:35 GMT
ETag: "ec-53a0004a26c6d"
Accept-Ranges: bytes
Content-Length: 236
Vary: Accept-Encoding
Content-Type: text/html


root@site1:~#  curl  site1.local
<html xmlns="">
<h1> Hi, This is </h1>

Repeat the step 2 for site2 ( ) and site3 ( ).

In proxy server add all three web servers entry ( IPADDRESS HOSTNAME ) apart from its own hostname as load-balancer.local

root@load-balancer:~# vi  /etc/hosts localhost load-balancer.local site1.local site2.local site3.local

Setup hostname of proxy server

root@load-balancer:~# vi /etc/hostname

3. Install HAProxy

Before installing it update Ubuntu. Execute the following command as root or using sudo to update ubuntu.

root@load-balancer:~# apt-get update

Now update packages on the system.

root@load-balancer:~# apt-get upgrade

Install it by executing following command in the terminal.

root@load-balancer:~# apt-get install haproxy

To enable the service as daemon, edit /etc/defaults/haproxy and add the following line.

root@load-balancer:~# vi /etc/defaults/haproxy

# Add extra flags here
#EXTRAOPTS="-de -m 16"

Start up the service

root@load-balancer:~# service haproxy start

4. Configure HAProxy

The configuration file located in /etc/haproxy/haproxy.cfg and has two parts global and proxies, Global section sets process-wide parameters and proxy section consists of the defaults, listen, front-end, and back-end sections.

Edit the configuration file with the text editor vi

root@load-balancer:~# vi /etc/haproxy/haproxy.cfg

The default configuration file will look something like the following.  Keep the global and default section as it is.

Global section

log local0
log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy

# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private

# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
ssl-default-bind-options no-sslv3

Default section

log     global
mode    http
option  httplog
option  dontlognull
timeout connect 5000
timeout client  50000
timeout server  50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http

Adding Listener:

A "front end" section describes a set of listening sockets accepting client connections. The front-end defines how requests should be handled and sent to the back-end server:

frontend Local_Server
mode http
default_backend My_Web_Servers

Adding Back-end Web Servers:

A "back-end" section describes a set of servers to which the proxy will connect to forward incoming connections. As per above configuration load balancer is now listening on port 80. Now define the back-end web servers where it will send the request.

backend My_Web_Servers
mode http
balance roundrobin
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1rnHost:localhost
server site1.local
server site2.local
server site3.local

You can add “check” parameter at the end of above three line to check health parameter of your web servers.

You can use other balancing algorithm  depending on your requirement.

Selects the server with the least number of connections--it is recommended for longer sessions. Servers in the same backend are also rotated in a round-robin fashion.

This selects which server to use based on a hash of the source IP i.e. your user's IP address. This is one method to ensure that a user will connect to the same server.

Enable Stats (Optional)

Now if you want you can enable statistics by adding following in configuration file.

listen stats
bind :9000
stats enable
stats hide-version
stats refresh 20s
stats show-node
stats uri /stats

5. Restart HAProxy

Since you have done with all necessary configurations for proxy server, verify configuration file before restarting service using following command.

root@load-balancer:~# haproxy -c -f /etc/haproxy/haproxy.cfg

If above command returned output as “configuration file is valid” then restart HAProxy service

root@load-balancer:~# service haproxy restart

Now check the status HAProxy server.

root@load-balancer:~#  service haproxy status

6. Test HAProxy

Before testing , make sure that you can ping the web-server ( site1.local, site2.local, site3.local) from  load-balancer.local

root@load-balancer:~# ping site1.local
PING site1.local ( 56(84) bytes of data.
64 bytes from site1.local ( icmp_seq=1 ttl=64 time=0.906 ms
64 bytes from site1.local ( icmp_seq=2 ttl=64 time=0.906 ms
64 bytes from site1.local ( icmp_seq=3 ttl=64 time=0.648 ms

root@load-balancer:~# ping site2.local
PING site2.local ( 56(84) bytes of data.
64 bytes from site2.local ( icmp_seq=1 ttl=64 time=3.02 ms
64 bytes from site2.local ( icmp_seq=2 ttl=64 time=0.687 ms
64 bytes from site2.local ( icmp_seq=3 ttl=64 time=0.778 ms

root@load-balancer:~# ping site3.local
PING site3.local ( 56(84) bytes of data.
64 bytes from site3.local ( icmp_seq=1 ttl=64 time=0.830 ms
64 bytes from site3.local ( icmp_seq=2 ttl=64 time=0.631 ms
64 bytes from site3.local ( icmp_seq=3 ttl=64 time=0.771 ms

Test HAPROXY  using CURL

To test execute the following script from the terminal , you will find that load balancer is sending request to three web servers in a round robin method.

root@load-balancer:~# while true; do curl; sleep 1; done
<html xmlns="">
<h1> Hi, This is </h1>

<html xmlns="">
<h1> Hi, This is </h1>

<html xmlns="">
<h1> Hi, This is </h1>

<html xmlns="">
<h1> Hi, This is </h1>

<html xmlns="">
<h1> Hi, This is </h1>

<html xmlns="">
<h1> Hi, This is </h1>




Test in browser:

Point your browser to http://load-balancer.local or http://Server-Public-IP you will get response from three web server in a round robin way confirming it is functioning with our expectation. With each refresh  the proxy server is sending request to back-end web server one by one.

You can also visit the stats url which is configured in the last section of  configuration file to confirm that the ports are opened for traffic. Simply navigate to Public IP or http://load-balancer.local  on port 9000.

For example, navigate to http://load-balancer.local:9000/stats

HAPROXY status

You can also monitor the status of server from terminal using HATOP. HATOP is a third-party tool which extracts the statistics from a socket file created by load balancer. Install HATOP by executing following command from the terminal.

root@load-balancer:~# apt-get install hatop

Normally when executing HATOP, you must use the -s parameter with the command sudo hatop -s /var/run/haproxy.sock. To avoid having to enter  the -s parameter when calling HATOP, you may insert the following line in your ~/.bashrc file:

export unix-socket=/var/run/haproxy.sock

7. Logging of HAProxy

Edit /etc/rsyslog.d/haproxy.conf and add the following lines in it.

local0.* -/var/log/haproxy_0.log
local1.* -/var/log/haproxy_1.log

Restart rsyslog

root@load-balancer:~# service rsyslog restart

Now check  logs using following command

root@load-balancer:~# tail -f /var/log/haproxy*.log

Also add the line “debug” in the global section of config file for verbose logging.


With HAProxy, you can increase the performance and availability of your web application. This tutorial is just an introduction to load balancing although it is capable of doing much more than what is described in this tutorial. You can improve the high availability by setting up floating IP between multiple load balancer to protect against failure in a single load balancer.

2 Comments... add one

  1. this line here doesnt appear to work if you have a server down:
    " option httpchk HEAD / HTTP/1.1rnHost:localhost"

    can you verifiy?
    if i comment it, and i put down 1 server, the other is selected.
    with that line error 503 is always coming up

    apart from that its a fine tutorial. Learned a lot


Leave a Comment