{"id":2359,"date":"2016-01-08T12:59:05","date_gmt":"2016-01-08T10:59:05","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/resources\/tutorials\/haproxy-load-balancer-centos\/"},"modified":"2026-04-23T14:13:42","modified_gmt":"2026-04-23T13:13:42","slug":"haproxy-load-balancer-centos","status":"publish","type":"tutorial","link":"https:\/\/upcloud.com\/global\/resources\/tutorials\/haproxy-load-balancer-centos\/","title":{"rendered":"How to install HAProxy load balancer on CentOS"},"content":{"rendered":"\n<div class=\"alert alert-info\">\n<h3>Try this guide out on UpCloud with our free trial!&nbsp;<a class=\"btn btn-cta-primary pull-right\" href=\"https:\/\/signup.upcloud.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Get started<\/a><\/h3>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Load balancing is a common solution for distributing&nbsp;web applications horizontally across multiple hosts while providing the users with a single point of access to the service.&nbsp;<a rel=\"noopener noreferrer\" href=\"http:\/\/www.haproxy.org\/\" target=\"_blank\">HAProxy<\/a> is one of the most popular&nbsp;open-source load-balancing software, which also offers high availability and proxy functionality.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/signup.upcloud.com\/\">Try UpCloud for free!<\/a><\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">HAProxy aims to optimise resource usage, maximise throughput, minimise response time, and avoid overloading any single resource. It is available for installation on many Linux distributions like CentOS 8 in this guide, but also on\u00a0<a href=\"https:\/\/upcloud.com\/global\/resources\/tutorials\/haproxy-load-balancer-debian\/\" target=\"_blank\" rel=\"noreferrer noopener\">Debian 8<\/a> and <a href=\"https:\/\/upcloud.com\/global\/resources\/tutorials\/haproxy-load-balancer-ubuntu\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ubuntu 16<\/a>\u00a0systems.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/haproxy-load-balancer-6.png\" alt=\"HAproxy load balancing\" class=\"wp-image-7166\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">HAProxy is particularly suited for very high-traffic websites and is therefore often used to improve web service reliability and performance for multi-server configurations. This guide lays out the steps for setting up HAProxy as a load balancer on CentOS 8 to its own cloud host which then directs the traffic to your web servers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As a pre-requirement for the best results, you should have a minimum of&nbsp;two web servers and a server for the load balancer. The web servers need to be running at least the basic web service such as <em>nginx<\/em> or <em>httpd<\/em> to test out the load balancing between them.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installing HAProxy CentOS 8<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">As a fast-developing open-source application HAProxy available for installation in the CentOS default repositories might not be the latest release. To find out what version number is being offered through the official channels enter the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo yum info haproxy<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">HAProxy has always three active stable versions of the releases, two of the latest versions in development plus a third older version that is still&nbsp;receiving critical updates. You can always check the currently newest stable version listed on the HAProxy website and then decide which version you wish to go with.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this guide, we will be installing the currently latest stable version of 2.0, which was not yet available in the standard repositories. Instead, you will need to&nbsp;install it from the source. But first, check that you have the prerequisites to download and compile the program.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo yum install gcc pcre-devel tar make -y<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Download the source code with the command below. You can check if there is a newer version available on the&nbsp;HAProxy <a href=\"http:\/\/www.haproxy.org\/#down\" target=\"_blank\" rel=\"noopener noreferrer\">download page<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">wget http:\/\/www.haproxy.org\/download\/2.0\/src\/haproxy-2.0.7.tar.gz -O ~\/haproxy.tar.gz<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once the download is complete, extract the files using the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">tar xzvf ~\/haproxy.tar.gz -C ~\/<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Change into the extracted source directory.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cd ~\/haproxy-2.0.7<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then compile the program for your system.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">make TARGET=linux-glibc<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And&nbsp;finally, install HAProxy itself.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo make install<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With that done, HAProxy is now installed but requires some additional steps to get it operational. Continue below with setting up the software and services.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setting up HAProxy for your server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Next, add&nbsp;the following directories and the statistics file for HAProxy records.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo mkdir -p \/etc\/haproxy\nsudo mkdir -p \/var\/lib\/haproxy \nsudo touch \/var\/lib\/haproxy\/stats<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create a symbolic link for the binary to allow you to run HAProxy commands&nbsp;as a normal user.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo ln -s \/usr\/local\/sbin\/haproxy \/usr\/sbin\/haproxy<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to add&nbsp;the proxy as a service to the system, copy the <tt>haproxy.init<\/tt> file from the examples to your <tt>\/etc\/init.d<\/tt> directory. Change the file permissions to make the script executable and then reload the systemd daemon.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo cp ~\/haproxy-2.0.7\/examples\/haproxy.init \/etc\/init.d\/haproxy\nsudo chmod 755 \/etc\/init.d\/haproxy\nsudo systemctl daemon-reload<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You will also need to enable the service to allow it to restart automatically at system boot-up.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo&nbsp;chkconfig haproxy on<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For general usage, it is also recommended to add a new user for HAProxy to be run under.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo useradd -r haproxy<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Afterwards, you can double-check the installed version number with the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">haproxy -v<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">HA-Proxy version 2.0.7 2019\/09\/27 - https:\/\/haproxy.org\/<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In this case, the version should be 2.0.7 as shown in the example output above.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lastly, the firewall on CentOS 8 is quite restrictive for this project by default. Use the following commands to allow the required services and reload the firewall.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo firewall-cmd --permanent --zone=public --add-service=http\nsudo firewall-cmd --permanent --zone=public --add-port=8181\/tcp\nsudo firewall-cmd --reload<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Configuring the load balancer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Setting up an HAProxy load balancer is a quite straightforward process. Basically, all you need to do is tell HAProxy what kind of connections it should be listening for and where the connections should be relayed to.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is done by creating a&nbsp;configuration file&nbsp;<tt>\/etc\/haproxy\/haproxy.cfg<\/tt> with the defining settings. You can read about the configuration options on the HAProxy <a href=\"https:\/\/cbonte.github.io\/haproxy-dconv\/2.0\/configuration.html\" target=\"_blank\" rel=\"noopener noreferrer\">documentation page<\/a> if you wish to find out more.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Load balancing at layer 4<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Start off with a basic setup. Create a new configuration file, for example, using <tt>vi<\/tt> with the command underneath.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo vi \/etc\/haproxy\/haproxy.cfg<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Add the following sections to the file. Replace the <span style=\"color: #ff0000;\"><tt>server_name<\/tt><\/span>&nbsp;with whatever you want to call your servers on the statistics page and the <span style=\"color: #ff0000;\"><tt>private_ip<\/tt><\/span>&nbsp;with the private IPs for the servers you wish to direct the web traffic. You can check the private IPs at your <a href=\"https:\/\/hub.upcloud.com\/networks\/private\" target=\"_blank\" rel=\"noopener noreferrer\">UpCloud control panel<\/a> and <em>Private network<\/em> tab under the&nbsp;<em>Network<\/em>&nbsp;menu.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">global\n   log \/dev\/log local0\n   log \/dev\/log local1 notice\n   chroot \/var\/lib\/haproxy\n   stats timeout 30s\n   user haproxy\n   group haproxy\n   daemon\n\ndefaults\n   log global\n   mode tcp\n   option httplog\n   option dontlognull\n   timeout connect 5000\n   timeout client 50000\n   timeout server 50000\n\nfrontend http_front\n   bind *:80\n   stats uri \/haproxy?stats\n   default_backend http_back\n\nbackend http_back\n   balance roundrobin\n   server <span style=\"color: #ff0000;\">server_name1<\/span> <span style=\"color: #ff0000;\">private_ip1<\/span>:80 check\n   server <span style=\"color: #ff0000;\">server_name2<\/span> <span style=\"color: #ff0000;\">private_ip2<\/span>:80 check<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This defines a layer 4 load balancer with a front-end name&nbsp;<tt>http_front<\/tt> listening to the port number <tt>80<\/tt>, which then&nbsp;directs the traffic to the default backend named&nbsp;<tt>http_back<\/tt>. The additional <tt>stats URI \/haproxy?stats<\/tt> enables the statistics page at that specified address.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Different load balancing algorithms<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Configuring the servers in the backend section allows HAProxy to use these servers for load balancing&nbsp;according to the <tt>roundrobin<\/tt>&nbsp;algorithm whenever available.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The balancing algorithms are used to decide which server at the backend each connection is transferred to. Some of the useful options include the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Roundrobin: Each server is used in turns according to its weights. This is the smoothest and fairest algorithm when the servers\u2019 processing time remains equally distributed. This algorithm is dynamic, which allows server weights to be adjusted on the fly.<\/li>\n\n\n\n<li>Leastconn:&nbsp;The server with the lowest number of connections is chosen. Round-robin is performed between&nbsp;servers with the same&nbsp;load. Using this algorithm is recommended with&nbsp;long sessions, such as LDAP, SQL, TSE, etc, but it is not very well&nbsp;suited for short sessions such as HTTP.<\/li>\n\n\n\n<li>First:&nbsp;The first server with available connection slots receives the&nbsp;connection. The servers are chosen from the lowest numeric&nbsp;identifier to the highest, which&nbsp;defaults to the server\u2019s position on the farm. Once a server&nbsp;reaches its <tt>maxconn<\/tt> value, the next server is used.<\/li>\n\n\n\n<li>Source:&nbsp;The source IP address is hashed and divided by the total&nbsp;weight of the running servers to designate which server will&nbsp;receive the request. This way&nbsp;the same client IP&nbsp;address will always reach the same server while&nbsp;the servers stay the same.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Configuring load balancing for layer 7<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Another possibility is to configure the load balancer&nbsp;to work on layer 7, which is useful when parts of your web application are located on different hosts. This can be accomplished by conditioning the connection transfer for example by the URL.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open the HAProxy configuration file with a text editor.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo vi \/etc\/haproxy\/haproxy.cfg<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then set the front and backend segments according to the example below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">defaults\n   ...\n   <span style=\"color: #ff0000;\">mode http<\/span>\n   ...\n\nfrontend http_front\n   bind *:80\n   stats uri \/haproxy?stats\n   acl url_blog path_beg \/blog\n   use_backend blog_back if url_blog\n   default_backend http_back\n\nbackend http_back\n   balance roundrobin\n   server <span style=\"color: #ff0000;\">server_name1<\/span> <span style=\"color: #ff0000;\">private_ip1<\/span>:80 check\n   server <span style=\"color: #ff0000;\">server_name2<\/span> <span style=\"color: #ff0000;\">private_ip2<\/span>:80 check\n\nbackend blog_back\n   server <span style=\"color: #ff0000;\">server_name3<\/span> <span style=\"color: #ff0000;\">private_ip3<\/span>:80 check<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The front end declares an ACL rule named <tt>url_blog<\/tt> that applies to all connections with paths that begin with <tt>\/blog<\/tt>.&nbsp;<tt>Use_backend<\/tt> defines that connections matching the <tt>url_blog<\/tt> condition should be served by the backend named <tt>blog_back<\/tt>, while all other requests are handled by the default backend.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On the backend side, the configuration sets up two server groups, <tt>http_back<\/tt>&nbsp;like before and the new one&nbsp;called <tt>blog_back<\/tt> that servers specifically connections to <tt>example.com\/blog<\/tt>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After making the configurations, save the file and restart HAProxy with the next command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl restart haproxy<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you get any errors or warnings at startup, check the configuration for any mistypes and that you have created all the necessary files and folders, then try restarting again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the&nbsp;setup<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">With the HAProxy configured and running, open your load balancer server\u2019s public IP in a web browser and check that you get connected to your backend correctly. The parameter <tt>stats uri<\/tt>&nbsp;in the configuration enables the statistics page at the defined address.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">http:\/\/load_balancer_public_ip\/haproxy?stats<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When you load&nbsp;the statistics page and all of your servers are listed in green your configuration was successful!<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/haproxy-207-2.png\" alt=\"HAProxy 1.7.8 statistics page\" class=\"wp-image-10737\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The statistics&nbsp;page contains some helpful information to keep track of your web hosts including up and downtimes and session counts. If a server is listed in red, check that the server is powered on and that you can ping it from the load balancer machine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In case your load balancer does not reply, check that HTTP connections are not getting blocked by the firewall. Also, confirm that HAProxy is running with the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl status haproxy<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Password protecting the statistics page<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Having the statistics page simply listed at the front end, however, is publicly open for anyone to view, which might not be such a good idea. Instead, you can set it up to its own port number by adding the example below to the end of your <tt>haproxy.cfg<\/tt> file. Replace the <span style=\"color: #ff0000;\"><tt>username<\/tt><\/span> and <span style=\"color: #ff0000;\"><tt>password<\/tt><\/span> with something secure.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">listen stats\n   bind *:8181\n   stats enable\n   stats uri \/\n   stats realm Haproxy Statistics\n   stats auth <span style=\"color: #ff0000;\">username<\/span>:<span style=\"color: #ff0000;\">password<\/span><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After adding the new <tt>listen<\/tt>&nbsp;group, remove the old reference to the <tt>stats uri<\/tt> from the <tt>frontend<\/tt>&nbsp;group. When done, save the file and restart HAProxy again.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl restart haproxy<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then open the load balancer again with the new port number, and log in with the username and password you set in the configuration file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">http:\/\/load_balancer_public_ip:8181<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check that your servers are still reporting all green and then open just the load balancer IP without any port numbers on your web browser.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">http:\/\/load_balancer_public_ip\/<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If your backend servers have at least slightly different landing pages you will notice that each time you reload the page you get a reply from a different host. You can try out different balancing algorithms in the configuration section or take a look at the full <a href=\"https:\/\/cbonte.github.io\/haproxy-dconv\/\" target=\"_blank\" rel=\"noopener noreferrer\">documentation<\/a>.<\/p>\n\n\n\n<div class=\"alert alert-info\">\n<p><a class=\"btn btn-cta-primary pull-right\" href=\"https:\/\/signup.upcloud.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Get started<\/a><\/p>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusions: HAProxy load balancer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Congratulations on successfully configuring the HAProxy load balancer! With a basic load balancer setup, you can considerably increase your web application performance and availability. This guide is however just an introduction to load balancing with HAProxy, which is capable of much more than what could be covered in first-time setup instruction. We recommend experimenting with different configurations with the help of the extensive <a href=\"https:\/\/cbonte.github.io\/haproxy-dconv\/2.0\/configuration.html\" target=\"_blank\" rel=\"noopener noreferrer\">documentation<\/a> available for HAProxy, and then start planning the load balancing for your production environment.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While using multiple hosts to protect your web service with redundancy, the load balancer itself can still leave a single point of failure. You can further improve the high availability by setting up a floating IP between multiple load balancers. You can find out more about this in our article on <a href=\"https:\/\/upcloud.com\/global\/resources\/tutorials\/floating-ip-addresses\/\" target=\"_blank\" rel=\"noreferrer noopener\">floating IPs on UpCloud<\/a>.<\/p>\n","protected":false},"author":3,"featured_media":26929,"comment_status":"open","ping_status":"closed","template":"","community-category":[223,274],"class_list":["post-2359","tutorial","type-tutorial","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2359","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/tutorial"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=2359"}],"version-history":[{"count":1,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2359\/revisions"}],"predecessor-version":[{"id":6442,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2359\/revisions\/6442"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=2359"}],"wp:term":[{"taxonomy":"community-category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/community-category?post=2359"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}