{"id":13797,"date":"2022-07-30T22:35:49","date_gmt":"2022-07-30T19:35:49","guid":{"rendered":"https:\/\/kifarunix.com\/?p=13797"},"modified":"2024-03-09T16:14:29","modified_gmt":"2024-03-09T13:14:29","slug":"deploy-haproxy-as-a-docker-container","status":"publish","type":"post","link":"https:\/\/kifarunix.com\/deploy-haproxy-as-a-docker-container\/","title":{"rendered":"Deploy HAProxy as a Docker Container"},"content":{"rendered":"\n

Follow through this tutorial to learn how to deploy HAProxy as a Docker container. HAProxy<\/a> “is a free, very fast and reliable reverse-proxy offering\u00a0high availability,\u00a0load balancing, and proxying for TCP and HTTP-based applications<\/em>“.<\/p>\n\n\n\n

Deploy HAProxy as a Docker Container<\/h2>\n\n\n\n

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.<\/p>\n\n\n\n

Install Docker on Linux<\/h3>\n\n\n\n

Check our previous tutorials on how to install Docker on Linux<\/a>.<\/p>\n\n\n\n

Download HAProxy Official Docker Image<\/h3>\n\n\n\n

Once the Docker is installed, you can then pull the official latest HAProxy Docker image from Docker Hub;<\/p>\n\n\n\n

docker pull haproxy<\/code><\/pre>\n\n\n\n

You can list available images using the command below;<\/p>\n\n\n\n

docker images<\/code><\/pre>\n\n\n\n

Create Your HAProxy Configuration<\/h3>\n\n\n\n

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.<\/p>\n\n\n\n

In our setup, we have placed the configuration under the \/opt\/haproxy<\/code> directory as haproxy.cfg<\/code>.<\/p>\n\n\n\n

This is how our sample configuration file looks like;<\/p>\n\n\n\n

cat \/opt\/haproxy\/haproxy.cfg<\/code><\/pre>\n\n\n\n
global\n    log         stdout format raw local0\n    stats socket \/var\/lib\/haproxy\/stats\n\ndefaults\n    mode                    http\n    log                     global\n    option                  httplog\n    option                  dontlognull\n    option http-server-close\n    option forwardfor       except 127.0.0.0\/8\n    option                  redispatch\n    retries                 3\n    timeout http-request    10s\n    timeout queue           1m\n    timeout connect         10s\n    timeout client          1m\n    timeout server          1m\n    timeout http-keep-alive 10s\n    timeout check           10s\n    maxconn                 3000\n    \n\nfrontend main\n    bind \t*:80 \n    default_backend web01\n    http-request capture req.hdr(Host) len 64\n    http-request capture req.hdr(Referer) len 64\n    http-request capture req.hdr(Content-Lenght) len 64\n    http-request capture req.hdr(User-Agent) len 64\n\nbackend web01\n    server  backend01   192.168.57.47:80 check\n\nlisten stats\n    bind  *:8888   \n    stats enable                      \n    stats hide-version              \n    stats refresh 30s               \n    stats show-node                 \n    stats auth rproxy:P@ssw0rd     \n    stats uri \/stats\n<\/code><\/pre>\n\n\n\n

For HAProxy configured with SSL\/TLS for both the frontend and backend, as well as the HAProxy stats page SSL\/TLS;<\/p>\n\n\n\n

\nglobal\n    log         stdout format raw local0\n    stats socket \/var\/lib\/haproxy\/stats\n    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\n    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n    ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets\n\ndefaults\n    mode                    http\n    log                     global\n    option                  httplog\n    option                  dontlognull\n    option http-server-close\n    option forwardfor       except 127.0.0.0\/8\n    option                  redispatch\n    retries                 3\n    timeout http-request    10s\n    timeout queue           1m\n    timeout connect         10s\n    timeout client          1m\n    timeout server          1m\n    timeout http-keep-alive 10s\n    timeout check           10s\n    maxconn                 3000\n    \n\nfrontend main\n    bind\t*:80\n    bind \t*:443 ssl  crt  \/usr\/local\/etc\/haproxy\/cert.pem\n    http-request redirect scheme https code 301 if !{ ssl_fc }\n    default_backend web01\n    http-request capture req.hdr(Host) len 64\n    http-request capture req.hdr(Referer) len 64\n    http-request capture req.hdr(Content-Lenght) len 64\n    http-request capture req.hdr(User-Agent) len 64\n\nbackend web01\n    server  backend01   backend.kifarunix-demo.com:443 check ssl verify none\n\nlisten stats\n    bind  *:8888 ssl  crt  \/usr\/local\/etc\/haproxy\/cert.pem\n    stats enable                      \n    stats hide-version              \n    stats refresh 30s               \n    stats show-node                 \n    stats auth rproxy:P@ssw0rd     \n    stats uri \/stats\n<\/code><\/pre>\n\n\n\n

Check HAProxy Configuration Syntax<\/h3>\n\n\n\n

Once you have the configuration file ready, you need to test it for validity. This can be done by running the command below;<\/p>\n\n\n\n

docker run -it --rm -v \/opt\/haproxy\/haproxy.cfg:\/usr\/local\/etc\/haproxy\/haproxy.cfg \\\n--name haconfig-syntax-check haproxy haproxy -c -f \/usr\/local\/etc\/haproxy\/haproxy.cfg<\/code><\/pre>\n\n\n\n

The command above basically creates a docker container haconfig-syntax-check<\/strong> using the haproxy<\/strong> image downloaded above, mounts our \/opt\/haproxy\/haproxy.cfg<\/code> config on the container \/usr\/local\/etc\/haproxy\/haproxy.cfg<\/code>, and run the test using the command haproxy haproxy -c -f \/usr\/local\/etc\/haproxy\/haproxy.cfg<\/code><\/strong>.<\/p>\n\n\n\n

If all is good, you should get such an output as Configuration file is valid<\/strong><\/code>.<\/p>\n\n\n\n

Otherwise, errors will be printed to standard output.<\/p>\n\n\n\n

For the config with SSL\/TLS enabled;<\/p>\n\n\n\n

docker run -it --rm -v \/opt\/haproxy\/:\/usr\/local\/etc\/haproxy\/ \\\n--name haconfig-syntax-check haproxy haproxy \\\n-c -f \/usr\/local\/etc\/haproxy\/haproxy.cfg<\/code><\/pre>\n\n\n\n

In this example, the certificate files and haproxy.cfg file is placed on the host directory, \/opt\/haproxy\/<\/code><\/strong> which mounted on \/usr\/local\/etc\/haproxy\/<\/code><\/strong> on the HAProxy docker container.<\/p>\n\n\n\n

Create HAProxy Docker Network<\/h3>\n\n\n\n

To isolate containers into their own container-only networks, you need to create a Docker network<\/a>.<\/p>\n\n\n\n

Run the command below to create Docker network. You can name your network as you wish.<\/p>\n\n\n\n

docker network create haproxynet<\/code><\/pre>\n\n\n\n

By default, a bridged network is created.<\/p>\n\n\n\n

You can list available Docker networks;<\/p>\n\n\n\n

docker network ls<\/code><\/pre>\n\n\n\n
NETWORK ID     NAME           DRIVER    SCOPE\na86e1291a1b1   bridge         bridge    local\n752b45df0a54   haproxynet     bridge    local\n<\/strong>623092a3cbbc   host           host      local\n71a9309810ee   none           null      local\n82b49e609d04   root_default   bridge    local<\/code><\/pre>\n\n\n\n

Deploy HAProxy Docker Container<\/h3>\n\n\n\n

You are now ready to deploy HAProxy Docker container.<\/p>\n\n\n\n

docker run -d --network haproxynet --name haproxy \\\n-v \/opt\/haproxy\/haproxy.cfg:\/usr\/local\/etc\/haproxy\/haproxy.cfg \\\n-p 80:80 -p 8888:8888 haproxy<\/code><\/pre>\n\n\n\n

The command creates a Docker container named haproxy<\/strong> using the haproxy<\/strong> image, mounts our configuration \/opt\/haproxy\/haproxy.cfg<\/strong><\/code> in the Docker container as \/usr\/local\/etc\/haproxy\/haproxy.cfg<\/code> and run it in the background, -d<\/code><\/strong>. It then exposes the HAProxy container port 80 on hosts port 80 (-p 80:80<\/code><\/strong>) and -p 8888:8888<\/strong><\/code> for stats.<\/p>\n\n\n\n

docker ps<\/code><\/pre>\n\n\n\n
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                                                          NAMES\n93ea8acc4644   haproxy   \"docker-entrypoint.s\u2026\"   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<\/code><\/pre>\n\n\n\n

Open Port 80\/443\/8888 on Firewall to allow external access.<\/p>\n\n\n\n

If you are using HAProxy with SSL enabled;<\/p>\n\n\n\n

docker run -d --network haproxynet --name haproxy \\\n-v \/opt\/haproxy\/:\/usr\/local\/etc\/haproxy\/ -p 80:80 \\\n-p 443:443 -p 8888:8888 haproxy<\/code><\/pre>\n\n\n\n

You can now access your web server using the address http:\/\/haproxy-ip-or-hostname<\/strong>.<\/p>\n\n\n\n

You can access the HAProxy stats using the address http[s]:\/\/haproxy-ip-or-hostname:8888<\/strong> and use the credentials set.<\/p>\n\n\n\n

\"deploy<\/figure><\/a><\/div>\n\n\n\n

You can also view the Docker container logs manually;<\/p>\n\n\n\n

docker logs --tail -20 haproxy<\/code><\/pre>\n\n\n\n
\n...\n192.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\"\n192.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\"\n192.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\"\n192.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\"\n192.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\"\n192.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\"\n192.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\"\n192.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\"\n192.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\"\n192.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\"\n<\/code><\/pre>\n\n\n\n

You can also view the logs automatically using Dozzle.<\/p>\n\n\n\n

And that is how you can run HAProxy as a Docker container.<\/p>\n\n\n\n

Other Tutorials<\/h3>\n\n\n\n

Install Guacamole as Docker Container on Rocky Linux<\/a><\/p>\n\n\n\n

Install ModSecurity 3 with Apache in a Docker Container<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"

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\u00a0high availability,\u00a0load<\/p>\n","protected":false},"author":3,"featured_media":13832,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rank_math_lock_modified_date":false,"footnotes":""},"categories":[121,1076,1077,1032,92,36],"tags":[5726,5728,1033,5727,5729],"class_list":["post-13797","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-howtos","category-containers","category-docker","category-haproxy","category-load-balancers","category-virtualization","tag-deploy-haproxy-as-docker","tag-docker-container-haproxy","tag-haproxy","tag-haproxy-docker-container","tag-haproxy-ssl-docker-container","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-50","resize-featured-image"],"_links":{"self":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/13797"}],"collection":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/comments?post=13797"}],"version-history":[{"count":8,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/13797\/revisions"}],"predecessor-version":[{"id":20581,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/13797\/revisions\/20581"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media\/13832"}],"wp:attachment":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media?parent=13797"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/categories?post=13797"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/tags?post=13797"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}

Install Dozzle Real-Time Log Viewer for Docker Containers<\/a><\/p>\n\n\n\n