How to install and configure haproxy on Linux Ubuntu Debian

haproxy is one of the best known and widely used Open Source load balancers out there and a strong competitor to nginx.  

haproxy is used by many large sites per Wikipedia:

HAProxy is used by a number of high-profile websites including GoDaddy, GitHub, Bitbucket,[6] Stack Overflow,[7] Reddit, Slack,[8], Tumblr, Twitter[9][10] and Tuenti[11] and is used in the OpsWorks product from Amazon Web Services.[12]


According to some stats data haproxy is even more popular than the AWS Elastic Load Balancer:


Step 1 - Install

apt install haproxy
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages were automatically installed and are no longer required:
  acl ebtables galera-3 git git-man iproute2 less libatm1 libconfig-inifiles-perl libdbd-mysql-perl libdbi-perl liberror-perl libjemalloc1 liblzo2-2 libuv1 lsof
  mariadb-common netcat netcat-traditional patch pigz runc socat squashfs-tools ubuntu-fan xdelta3
Use 'apt autoremove' to remove them.
Suggested packages:
  vim-haproxy haproxy-doc
The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 34 not upgraded.
Need to get 1116 kB of archives.
After this operation, 2374 kB of additional disk space will be used.
Get:1 bionic-updates/main amd64 haproxy amd64 1.8.8-1ubuntu0.13 [1116 kB]
Fetched 1116 kB in 2s (657 kB/s)  
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
    LANGUAGE = (unset),
    LC_ALL = (unset),
    LANG = "C.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
Selecting previously unselected package haproxy.
(Reading database ... 20143 files and directories currently installed.)
Preparing to unpack .../haproxy_1.8.8-1ubuntu0.13_amd64.deb ...
Unpacking haproxy (1.8.8-1ubuntu0.13) ...
Setting up haproxy (1.8.8-1ubuntu0.13) ...
Created symlink /etc/systemd/system/ → /lib/systemd/system/haproxy.service.
invoke-rc.d: could not determine current runlevel
invoke-rc.d: WARNING: No init system and policy-rc.d missing! Defaulting to block.
Processing triggers for systemd (237-3ubuntu10.57) ...


Step 2 - Configure haproxy.cfg file

vi /etc/haproxy/haproxy.cfg

Here is how the defaults of haproxy.cfg look:

        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        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:
        # An alternative list with additional directives can be obtained from
        ssl-default-bind-options no-sslv3

        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


More info about configuring haproxy from the authors.


Let's add a frontend and backend

At the moment the load balancer does nothing and essentially has no usable configuration.  We're going to add a frontend that listens on localhost and is bound to port 8080.

The frontend itself is just the entry point for the user, the frontend is configured on a certain IP and port that we define and the next step is that we'll have to define a "backend" that is the actual source server (eg. our Apache running PHP or another application)

Add this frontend and backend config to the end of haproxy.cfg

frontend rttfrontend
  default_backend rttbackendservers

backend rttbackendservers
  server backendserver01

 cache rttcache
   # Total size of the cache in MB
   total-max-size 500

   # Max size of any single item in bytes
   max-object-size 100000

   # Time to live for each item in seconds
   # This can be overridden with a Cache-Control header
   max-age 3000

This config allows you to scale out as much as you need, for example you could add dozens or hundreds of backend servers with different IPs and ports.

You may also want to add the "check" option after each server so requests won't be sent to dead or overloaded servers:

server rttbackendserver01 check

We can make it more like a CDN by enabling cache, so the backend servers don't need to be contacted if we have a cache hit:

cache rttcache
   # Total size of the cache in MB
   total-max-size 500

   # Max size of any single item in bytes
   max-object-size 10000

   # Time to live for each item in seconds
   # This can be overridden with a Cache-Control header
   max-age 3000


In older versions like 1.8, the max-object-size option does not exist.

You'll find the cache doesn't work unless you set this option in your global config:

tune.bufsize 9999999

Here is an example of how much performance can be gained by using a caching frontend haproxy server:

In our first example below the page in question has not been cached and has a TTFB of 0.486955 seconds and total load time of .677587 seconds.

curl -k -o /dev/null -w "Connect: %{time_connect} TTFB: %{time_starttransfer} Total time: %{time_total} \n" $site
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 16413  100 16413    0     0  24243      0 --:--:-- --:--:-- --:--:-- 24207
Connect: 0.047765 TTFB: 0.486955 Total time: 0.677587

Now after we loaded the site and it is in the cache notice the difference in performance:

TTFB is now 0.090424 and total load time of .135752

TTFB is now 5.38X faster and load time was 4.99X faster!

curl -k -o /dev/null -w "Connect: %{time_connect} TTFB: %{time_starttransfer} Total time: %{time_total} \n" $site
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 16413  100 16413    0     0   118k      0 --:--:-- --:--:-- --:--:--  118k
Connect: 0.044437 TTFB: 0.090424 Total time: 0.135752


How To enable Stats

By enabling stats we can check on things like how our cache is doing:

Add this to the globa section:

    stats socket ipv4@ level admin
    stats socket /var/run/hapee-lb.sock mode 666 level admin


You can echo commands via socat to see the status of things like you cache:

echo "show cache" | socat stdio /var/run/hapee-lb.sock
0x7f5f1ef9503a: rtt (shctx:0x7f5f1ef95000, available blocks:512000)
0x7f5f1ef950ac hash:3598866029 size:16657 (17 blocks), refcount:0, expire:25695


Here is a list of commands that can be sent:

echo "help" | socat stdio /var/run/hapee-lb.sock
Unknown command. Please enter one of the following commands only :
  help           : this message
  prompt         : toggle interactive mode with prompt
  quit           : disconnect
  show tls-keys [id|*]: show tls keys references or dump tls ticket keys when id specified
  set ssl tls-key [id|keyfile] <tlskey>: set the next TLS key for the <id> or <keyfile> listener to <tlskey>
  show errors    : report last request and response errors for each proxy
  disable agent  : disable agent checks (use 'set server' instead)
  disable health : disable health checks (use 'set server' instead)
  disable server : disable a server for maintenance (use 'set server' instead)
  enable agent   : enable agent checks (use 'set server' instead)
  enable health  : enable health checks (use 'set server' instead)
  enable server  : enable a disabled server (use 'set server' instead)
  set maxconn server : change a server's maxconn setting
  set server     : change a server's state, weight or address
  get weight     : report a server's current weight
  set weight     : change a server's weight (deprecated)
  show sess [id] : report the list of current sessions or dump this session
  shutdown session : kill a specific session
  shutdown sessions server : kill sessions on a server
  clear table    : remove an entry from a table
  set table [id] : update or create a table entry's data
  show table [id]: report table usage stats or dump this table's contents
  clear counters : clear max statistics counters (add 'all' for all counters)
  show info      : report information about the running process
  show stat      : report counters for each proxy and server
  show schema json : report schema used for stats
  show startup-logs : report logs emitted during HAProxy startup
  show resolvers [id]: dumps counters from all resolvers section and
                     associated name servers
  set maxconn global : change the per-process maxconn setting
  set rate-limit : change a rate limiting value
  set severity-output [none|number|string] : set presence of severity level in feedback information
  set timeout    : change a timeout setting
  show env [var] : dump environment variables known to the process
  show cli sockets : dump list of cli sockets
  show fd [num] : dump list of file descriptors in use
  show activity : show per-thread activity stats (for support/developers)
  disable frontend : temporarily disable specific frontend
  enable frontend : re-enable specific frontend
  set maxconn frontend : change a frontend's maxconn setting
  show servers state [id]: dump volatile server information (for backend <id>)
  show backend   : list backends in the current running config
  shutdown frontend : stop a specific frontend
  set dynamic-cookie-key backend : change a backend secret key for dynamic cookies
  enable dynamic-cookie backend : enable dynamic cookies on a specific backend
  disable dynamic-cookie backend : disable dynamic cookies on a specific backend
  show cache     : show cache status
  add acl        : add acl entry
  clear acl <id> : clear the content of this acl
  del acl        : delete acl entry
  get acl        : report the patterns matching a sample for an ACL
  show acl [id]  : report available acls or dump an acl's contents
  add map        : add map entry
  clear map <id> : clear the content of this map
  del map        : delete map entry
  get map        : report the keys and values matching a sample for a map
  set map        : modify map entry
  show map [id]  : report available maps or dump a map's contents
  show pools     : report information about the memory pools usage


install, configure, haproxy, linux, ubuntu, debianhaproxy, widely, balancers, competitor, nginx, aws, balancer, apt, lists, dependency, packages, automatically, installed, acl, ebtables, galera, git, iproute, libatm, libconfig, inifiles, perl, libdbd, mysql, libdbi, liberror, libjemalloc, liblzo, libuv, lsof, mariadb, netcat, pigz, runc, socat, squashfs, xdelta, autoremove, vim, upgraded, newly, kb, archives, additional, disk, http, archive, bionic, updates, amd, fetched, locale, settings, unset, lc_all, lang, quot, utf, supported, lc_ctype, default, directory, lc_messages, selecting, previously, unselected, database, directories, currently, preparing, unpack, haproxy_, _amd, deb, unpacking, symlink, etc, systemd, multi, user, rarr, lib, invoke, rc, determine, runlevel, init, defaulting, processing, triggers, cfg, vi, defaults, global, dev, chroot, var, stats, socket, admin, mode, fd, listeners, timeout, daemon, ssl, locations, ca, certs, crt, ciphers, enabled, sockets, https, hynek, articles, hardening, servers, directives, obtained, mozilla, github, io, server, tls, config, generator, bind, ecdh, aesgcm, dh, aes, rsa, anull, md, dss, sslv, httplog, dontlognull, errorfile, errors, info, configuring, authors, frontend, backend, essentially, usable, configuration, listens, localhost, entry, configured, ip, define, ll, eg, apache, php, rttfrontend, default_backend, rttbackendservers, backendserver, allows, dozens, ips, ports, cdn, enabling, cache, contacted, rttcache, mb, bytes, overridden, header,

Latest Articles

  • How to resize a pdf without losing much quality in Linux Mint Ubuntu Debian Redhat Solution
  • qemu: could not load PC BIOS 'bios-256k.bin' solution
  • Proxmox How To Custom Partition During Install
  • Hyper-V Linux VM Boots to Black Screen, Storage, NIC Not Found Issues
  • Ubuntu Mint How to Fix Missing/Broken /dev and /dev/pts which causes terminal to immediately close exit and not work
  • How high can a Xeon CPU get?
  • bash fix PATH environment variable "command not found" solution
  • Ubuntu Linux Mint Debian Redhat Youtube Cannot Play HD or 4K videos, dropped frames or high CPU usage with Nvidia or AMD Driver
  • hostapd example configuration for high speed AC on 5GHz using WPA2
  • hostapd how to enable and use WPS to connect wireless devices like printers
  • Dell Server Workstation iDRAC Dead after Firmware Update Solution R720, R320, R730
  • Cloned VM/Server/Computer in Linux won't boot and goes to initramfs busybox Solution
  • How To Add Windows 7 8 10 11 to GRUB Boot List Dual Booting
  • How to configure OpenDKIM on Linux with Postfix and setup bind zonefile
  • Debian Ubuntu 10/11/12 Linux how to get tftpd-hpa server setup tutorial
  • efibootmgr: option requires an argument -- 'd' efibootmgr version 15 grub-install.real: error: efibootmgr failed to register the boot entry: Operation not permitted.
  • Apache Error Won't start SSL Cert Issue Solution Unable to configure verify locations for client authentication SSL Library Error: 151441510 error:0906D066:PEM routines:PEM_read_bio:bad end line SSL Library Error: 185090057 error:0B084009:x509 certif
  • Linux Debian Mint Ubuntu Bridge br0 gets random IP
  • redis requirements
  • How to kill a docker swarm