In this tutorial, we will teach you how to use HAProxy as a layer 7 load balancer to serve multiple applications from a single domain name or IP address. Load balancing can improve the performance, availability, and resilience of your environment.
Layer 7 reverse proxying and load balancing is suitable for your site if you want to have a single domain name that serves multiple applications, as the http requests can be analyzed to decide which application should receive the traffic.
This tutorial is written with WordPress and a static web site as examples, but its general concepts can be used with other applications to a similar effect.
Before continuing with this tutorial, you should have at least two applications running on separate servers. We will use a static website hosted on Nginx and WordPress as our two applications. If you want to follow this tutorial exactly, here are the tutorials that we used to set up our prerequisite environment:
Our starting environment looks like this:
In addition to your current environment, we will be creating the following VPSs:
If you are unfamiliar with basic load-balancing concepts or terminology, like layer 7 load balancing or backends or ACLs, here is an article that explains the basics: An Introduction to HAProxy and Load Balancing Concepts.
By the end of this tutorial, we want to have an environment that looks like this:
That is, your users will access both of your applications through http://example.com. All requests that begin with http://example.com/wordpress will be forwarded to your WordPress servers, and all of the other requests will be forwarded to your basic Nginx servers. Note that you do not necessarily need to load balance your applications to have them appear on a single domain, but we will cover load balancing in this tutorial.
Note: DigitalOcean Load Balancers are a fully-managed, highly available load balancing service. If you are running your application on DigitalOcean, the Load Balancer service may be able to replace HAProxy in these types of configurations. To try this out, follow our guide on setting up Load Balancers from step 2 instead of setting up HAProxy.
Create a new VPS with Private Networking. For this tutorial, we will call it haproxy-www.
In our haproxy-www VPS, let’s install HAProxy with apt-get:
sudo apt-get update
sudo apt-get install haproxy
We need to enable the HAProxy init script, so HAProxy will start and stop along with your VPS.
sudo vi /etc/default/haproxy
Change the value of ENABLED
to 1
to enable the HAProxy init script:
ENABLED=1
Save and quit. Now HAProxy will start and stop with your VPS. Also, you can now use the service
command to control your HAProxy. Let’s check to see if it is running:
user@haproxy-www:/etc/init.d$ sudo service haproxy status
haproxy not running.
It is not running. That’s fine, because it needs to be configured before we can use it. Let’s configure HAProxy for our environment next.
HAProxy’s configuration file is divided into two major sections:
Again, if you are unfamiliar with HAProxy or basic load-balancing concepts and terminology, please refer to this link: An Introduction to HAProxy and Load Balancing Concepts
All of the HAProxy configuration should be done on your HAProxy VPS, haproxy-www.
First, let’s make a copy of the default haproxy.cfg file:
cd /etc/haproxy; sudo cp haproxy.cfg haproxy.cfg.orig
Now open haproxy.cfg in a text editor:
sudo vi /etc/haproxy/haproxy.cfg
You will see that there are two sections already defined: global and defaults. First we will take a look at some of the default parameters.
Under defaults, look for the following lines:
mode http
option httplog
Selecting http as the mode configures HAProxy to perform layer 7, or application layer, load balancing. This means that the load balancer will look at the content of the http requests and forward it to the appropriate server based on the rules defined in the frontend. If you are unfamiliar with this concept, please read the Types of Load Balancing section in our Intro to HAProxy.
Do not close the config file yet! We will add the proxy configuration next.
The first thing we want to add is a frontend. For a basic layer 7 reverse proxying and load balancing setup, we will want to define an ACL that will be used to direct our traffic to the appropriate backend servers. There are many ACLs that can be used in HAProxy, and we will only cover one of them in this tutorial (path_beg)–for a complete list of ACLs in HAProxy, check out the official documentation: HAProxy ACLs
At the end of the file, let’s add our frontend, www. Be sure to replace haproxy_www_public_IP
with the public IP of your haproxy-www VPS:
<pre> frontend www bind <span class=“highlight”>haproxy_www_public_IP</span>:80 option http-server-close acl url_wordpress path_beg /wordpress use_backend wordpress-backend if url_wordpress default_backend web-backend </pre>
Here is an explanation of what each line in the frontend config snippet above means:
haproxy_www_public_IP
with haproxy-www’s public IP address. This tells HAProxy that this frontend will handle the incoming network traffic on this IP address and portAfter you are finished configuring the frontend, continue adding your first backend by adding the following lines. Be sure to replace the highlighted words with the appropriate values:
<pre> backend web-backend server web-1 <span class=“highlight”>web_1_private_IP</span>:80 check </pre>
Here is an explanation of what each line in the backend config snippet above means:
Then add the backend for your WordPress application :
<pre> backend wordpress-backend reqrep ^([^\ :])\ /<span class=“highlight”>wordpress</span>/(.) \1\ /\2 server wordpress-1 <span class=“highlight”>wordpress_1_private_IP</span>:80 check </pre>
Here is an explanation of what each line in the backend config snippet above means:
If you want to enable HAProxy stats, which can be useful in determining how HAProxy is handling incoming traffic, you will want to add the following into your configuration:
<pre>
listen stats :1936
stats enable
stats scope www
stats scope web-backend
stats scope wordpress-backend
stats uri /
stats realm Haproxy\ Statistics
stats auth <span class=“highlight”>user</span>:<span class=“highlight”>password</span>
</pre>
Here is an explanation of the non-trivial lines in the listen stats configuration snippet above:
Now save and quit. When you start HAProxy, the stats page will be available via http://haproxy_www_public_ip:1936/ once you start your HAProxy service. HAProxy is now ready to be started, but let’s enable logging first.
Enabling logging in HAProxy is very simple. First edit the rsyslog.conf file:
sudo vi /etc/rsyslog.conf
Then find the following two lines, and uncomment them to enable UDP syslog reception. It should look like the following when you are done:
$ModLoad imudp
$UDPServerRun 514
$UDPServerAddress 127.0.0.1
Now restart rsyslog to enable the new configuration:
sudo service rsyslog restart
HAProxy logging is is now enabled! The log file will be created at /var/log/haproxy.log
once HAProxy is started.
Now that your WordPress application’s URL has changed, we must update a couple of settings in WordPress.
On either WordPress server, edit your wp-config.php. It is located where you installed WordPress (in the tutorial, it was installed in /var/www/example.com but your installation may vary):
<pre> cd <span class=“highlight”>/var/www/example.com</span>; sudo vi wp-config.php </pre>
Find the line near the top that says define('DB_NAME', 'wordpress');
and add the following lines above it, substituting the highlighted values,:
<pre> define(‘WP_SITEURL’, ‘<span class=“highlight”>http://haproxy_www_public_IP</span>’); define(‘WP_HOME’, ‘<span class=“highlight”>http://haproxy_www_public_IP</span>’); </pre>
Save and quit. Now the WordPress URLs are configured to point to your load balancer instead of only your original WordPress server, which comes into play when you try and access the wp-admin Dashboard.
On haproxy-www, start HAProxy to make your config changes take effect:
sudo service haproxy restart
Now your applications are accessible through the same domain, example.com, via a layer 7 reverse proxy, but they are not yet load balanced. Your environment should look like the following diagram:
In accordance with the frontend that we defined earlier, here is a description of how HAProxy will forward your traffic:
If all you wanted to do was host multiple applications on a single domain, you are done! If you want to load balance your applications, you will need to read on.
To load balance a basic web server, all you need to do is create a new web server that has identical configuration and content as your original. We will call this new server: web-2.
You have two options when creating the new VPS:
Note: Both of the aforementioned methods do a one time copy of your server root contents. If you update any of your files on one of your server nodes, web-1 or web-2, make sure you synchronize the files again.
After your identical web server has been set up, add it to the web-backend in the HAProxy configuration.
On haproxy-www, edit haproxy.cfg:
sudo vi /etc/haproxy/haproxy.cfg
Find the web-backend section of the configuration:
<pre> backend web-backend server web-1 <span class=“highlight”>web_1_private_IP</span>:80 check </pre>
Then add your web-2 server on the next line:
<pre> server web-2 <span class=“highlight”>web_2_private_IP</span>:80 check </pre>
Save and quit. Now reload HAProxy to put your change into effect:
sudo service haproxy reload
Now your web-backend has two servers handling all of your non-WordPress traffic! It is load balanced!`
Load balancing an application such as WordPress is slightly more complicated than load balancing a static web server because you have to worry about things like synchronizing uploaded files and additional database users.
All of the steps that are required to create an additional, identical WordPress server are described in another load balancing tutorial: How To Use HAProxy as a Layer 4 Load Balancer for WordPress. Complete the three following steps from that tutorial to create your second WordPress server, wordpress-2:
Stop once you get to the section that is called Not Yet Load Balanced.
Once you have wordpress-2 created and you have your database set up correctly, all you have to do is add it to your wordpress-backend in the HAProxy configuration.
On haproxy-www, edit haproxy.cfg:
sudo vi /etc/haproxy/haproxy.cfg
Find the wordpress-backend section of the configuration:
<pre> backend wordpress-backend server wordpress-1 <span class=“highlight”>wordpress_1_private_IP</span>:80 check </pre>
Then add your wordpress-2 server on the next line:
<pre> server wordpress-2 <span class=“highlight”>wordpress_2_private_IP</span>:80 check </pre>
Save and quit. Now reload HAProxy to put your change into effect:
sudo service haproxy reload
Now your wordpress-backend has two servers handling all of your WordPress traffic! It is load balanced!
Now that you have completed this tutorial, you should be able to expand on the reverse proxying and load balancing concepts to add more applications and servers to your environment to make it fit your needs better. Remember that there are limitless ways to configure your environment, and you may need to dig into the HAProxy Configuration Manual if you have more complex requirements.
Additionally, if you are looking for another way to improve the performance of your WordPress instance, you may want to look into MySQL replication. Check out this tutorial that describes how set that up with WordPress:
<div class=“author”>By Mitchell Anicas</div>
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Adding a load balancer to your server environment is a great way to increase reliability and performance. The first tutorial in this series will introduce you to load balancing concepts and terminology, followed by two tutorials that will teach you how to use HAProxy to implement layer 4 or layer 7 load balancing in your own WordPress environment. The last tutorial covers SSL termination with HAProxy.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
hi, in which program can you create diagrams like you have created in this tutorial?
thanks.
Sometimes ACL is not being matched by haproxy and this makes some connection drops. Does anyone having similar issues. using HA-Proxy version 1.5.14 2015/07/02
Hi Can you tell me How To Use HAProxy As A Layer 7 Load Balancer For HTTPS ? THANKS
hey there ! i was trying to do reverse proxy for my nodejs application and my blog , i followed your tutorial , upon hitting ‘my_ip/’ the haproxy directs the traffic to my node app server , which is good , but on ‘my_ip/wordpress’ it shows me the error ‘404 not found , The requested URL /wordpress was not found on this server.’ help would be much appreciated -THANKS
Sweet tutorial man! Helped me figure out how to get Ruby on Rails and Wordpress on two different servers.
Quick question though. Because wordpress is installed in the root url of the wordpress server, but is accessed through /wordpress on the HAProxy server, would the correct url settings for the wordpress config be
http://haproxy_www_public_IP/wordpress
?For example:
If I leave out /wordpress in the wp_siteurl and wp_home, it kicks back to the root path for the admin dashboard which HAProxy doesn’t recognize, ie:
http://haproxy_www_public_IP/wp-login.php