Follow through this tutorial to learn how to deploy HAProxy as a Docker container. HAProxy “is a free, very fast and reliable reverse-proxy offering high availability, load balancing, and proxying for TCP and HTTP-based applications“.
Deploy HAProxy as a Docker Container
HAProxy can be run by installing it as a package using your specific Linux distribution package manager or by deploying it as a Docker container.
Install Docker on Linux
Check our previous tutorials on how to install Docker on Linux.
Download HAProxy Official Docker Image
Once the Docker is installed, you can then pull the official latest HAProxy Docker image from Docker Hub;
docker pull haproxy
You can list available images using the command below;
docker images
Create Your HAProxy Configuration
Depending on your needs, create your HAProxy configuration before hand on your host system. We will configure the HAProxy Docker container to use this configuration.
In our setup, we have placed the configuration under the /opt/haproxy
directory as haproxy.cfg
.
This is how our sample configuration file looks like;
cat /opt/haproxy/haproxy.cfg
global
log stdout format raw local0
stats socket /var/lib/haproxy/stats
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 10s
timeout check 10s
maxconn 3000
frontend main
bind *:80
default_backend web01
http-request capture req.hdr(Host) len 64
http-request capture req.hdr(Referer) len 64
http-request capture req.hdr(Content-Lenght) len 64
http-request capture req.hdr(User-Agent) len 64
backend web01
server backend01 192.168.57.47:80 check
listen stats
bind *:8888
stats enable
stats hide-version
stats refresh 30s
stats show-node
stats auth rproxy:P@ssw0rd
stats uri /stats
For HAProxy configured with SSL/TLS for both the frontend and backend, as well as the HAProxy stats page SSL/TLS;
global
log stdout format raw local0
stats socket /var/lib/haproxy/stats
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
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 10s
timeout check 10s
maxconn 3000
frontend main
bind *:80
bind *:443 ssl crt /usr/local/etc/haproxy/cert.pem
http-request redirect scheme https code 301 if !{ ssl_fc }
default_backend web01
http-request capture req.hdr(Host) len 64
http-request capture req.hdr(Referer) len 64
http-request capture req.hdr(Content-Lenght) len 64
http-request capture req.hdr(User-Agent) len 64
backend web01
server backend01 backend.kifarunix-demo.com:443 check ssl verify none
listen stats
bind *:8888 ssl crt /usr/local/etc/haproxy/cert.pem
stats enable
stats hide-version
stats refresh 30s
stats show-node
stats auth rproxy:P@ssw0rd
stats uri /stats
Check HAProxy Configuration Syntax
Once you have the configuration file ready, you need to test it for validity. This can be done by running the command below;
docker run -it --rm -v /opt/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg \
--name haconfig-syntax-check haproxy haproxy -c -f /usr/local/etc/haproxy/haproxy.cfg
The command above basically creates a docker container haconfig-syntax-check using the haproxy image downloaded above, mounts our /opt/haproxy/haproxy.cfg
config on the container /usr/local/etc/haproxy/haproxy.cfg
, and run the test using the command haproxy haproxy -c -f /usr/local/etc/haproxy/haproxy.cfg
.
If all is good, you should get such an output as Configuration file is valid
.
Otherwise, errors will be printed to standard output.
For the config with SSL/TLS enabled;
docker run -it --rm -v /opt/haproxy/:/usr/local/etc/haproxy/ \
--name haconfig-syntax-check haproxy haproxy \
-c -f /usr/local/etc/haproxy/haproxy.cfg
In this example, the certificate files and haproxy.cfg file is placed on the host directory, /opt/haproxy/
which mounted on /usr/local/etc/haproxy/
on the HAProxy docker container.
Create HAProxy Docker Network
To isolate containers into their own container-only networks, you need to create a Docker network.
Run the command below to create Docker network. You can name your network as you wish.
docker network create haproxynet
By default, a bridged network is created.
You can list available Docker networks;
docker network ls
NETWORK ID NAME DRIVER SCOPE
a86e1291a1b1 bridge bridge local
752b45df0a54 haproxynet bridge local
623092a3cbbc host host local
71a9309810ee none null local
82b49e609d04 root_default bridge local
Deploy HAProxy Docker Container
You are now ready to deploy HAProxy Docker container.
docker run -d --network haproxynet --name haproxy \
-v /opt/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg \
-p 80:80 -p 8888:8888 haproxy
The command creates a Docker container named haproxy using the haproxy image, mounts our configuration /opt/haproxy/haproxy.cfg
in the Docker container as /usr/local/etc/haproxy/haproxy.cfg
and run it in the background, -d
. It then exposes the HAProxy container port 80 on hosts port 80 (-p 80:80
) and -p 8888:8888
for stats.
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
93ea8acc4644 haproxy "docker-entrypoint.s…" 8 seconds ago Up 7 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:8888->8888/tcp, :::8888->8888/tcp haproxy
Open Port 80/443/8888 on Firewall to allow external access.
If you are using HAProxy with SSL enabled;
docker run -d --network haproxynet --name haproxy \
-v /opt/haproxy/:/usr/local/etc/haproxy/ -p 80:80 \
-p 443:443 -p 8888:8888 haproxy
You can now access your web server using the address http://haproxy-ip-or-hostname.
You can access the HAProxy stats using the address http[s]://haproxy-ip-or-hostname:8888 and use the credentials set.
You can also view the Docker container logs manually;
docker logs --tail -20 haproxy
...
192.168.56.1:56614 [29/Jul/2022:20:09:41.366] stats stats/ 0/0/0/0/0 200 21282 - - LR-- 1/1/0/0/0 0/0 "GET /stats HTTP/1.1"
192.168.56.1:56646 [29/Jul/2022:20:10:11.508] stats stats/ 0/0/0/0/0 200 21282 - - LR-- 1/1/0/0/0 0/0 "GET /stats HTTP/1.1"
192.168.56.1:56678 [29/Jul/2022:20:10:41.663] stats stats/ 0/0/0/0/0 200 21282 - - LR-- 1/1/0/0/0 0/0 "GET /stats HTTP/1.1"
192.168.56.1:56722 [29/Jul/2022:20:11:11.783] stats stats/ 0/0/0/0/0 200 21286 - - LR-- 1/1/0/0/0 0/0 "GET /stats HTTP/1.1"
192.168.56.1:56754 [29/Jul/2022:20:11:41.856] stats stats/ 0/0/0/0/0 200 21287 - - LR-- 1/1/0/0/0 0/0 "GET /stats HTTP/1.1"
192.168.56.1:56786 [29/Jul/2022:20:12:11.905] stats stats/ 0/0/0/0/0 200 21287 - - LR-- 1/1/0/0/0 0/0 "GET /stats HTTP/1.1"
192.168.56.1:56820 [29/Jul/2022:20:12:41.998] stats stats/ 0/0/0/0/0 200 21291 - - LR-- 1/1/0/0/0 0/0 "GET /stats HTTP/1.1"
192.168.56.1:53768 [29/Jul/2022:20:13:02.841] main web01/backend01 0/0/1/0/1 404 436 - - ---- 1/1/0/0/0 0/0 {192.168.56.124|||like Gecko) Chrome/104.0.0.0 Safari/537.36} "GET /index.php HTTP/1.1"
192.168.56.1:53768 [29/Jul/2022:20:13:09.760] main web01/backend01 0/0/2/1/3 200 3400 - - ---- 1/1/0/0/0 0/0 {192.168.56.124|||like Gecko) Chrome/104.0.0.0 Safari/537.36} "GET / HTTP/1.1"
192.168.56.1:53830 [29/Jul/2022:20:13:54.521] main web01/backend01 0/0/1/1/3 200 3400 - - ---- 1/1/0/0/0 0/0 {192.168.56.124|||like Gecko) Chrome/104.0.0.0 Safari/537.36} "GET /?doc=ls%20bin/bash HTTP/1.1"
You can also view the logs automatically using Dozzle.
Install Dozzle Real-Time Log Viewer for Docker Containers
And that is how you can run HAProxy as a Docker container.