An HAProxy configuration file guides the behavior of your HAProxy load balancer. In this post, we demonstrate its four most essential sections.
There are four essential sections to an HAProxy configuration file. They are global
, defaults
, frontend
, and backend
. These four sections define how the server as a whole performs, what your default settings are, and how client requests are received and routed to your backend servers.
If you compare the world of reverse proxies to an Olympic relay race, then global
, defaults
, frontend
and backend
are the star runners. Each section plays a vital role, handing the baton to the next in line. Like an Olympic relay team, an HAProxy load balancer’s power and performance is achieved by combining the unique talents of each section. Let’s meet them and see how they team up.
Watch our on-demand webinar “Introduction to HAProxy” to learn more about the basics of load balancing with HAProxy.
The Format
If you’re using HAProxy Enterprise to get ahold of its advanced features, the configuration file can be found at /etc/hapee-1.8/hapee-lb.cfg. If you’re using the Community Edition, it’s at /etc/haproxy/haproxy.cfg. You can test your configuration changes by calling the haproxy executable with the -c
parameter, such as:
haproxy -c -f /etc/hapee-1.8/hapee-lb.cfg |
The structure of this file is as follows:
global | |
# global settings here | |
defaults | |
# defaults here | |
frontend | |
# a frontend that accepts requests from clients | |
backend | |
# servers that fulfill the requests |
A section begins when a keyword like global
or defaults
is encountered and is comprised of all of the lines that follow until you reach another section keyword. Blank lines and indentation are ignored. So, the global
section continues until you get to, say, a defaults
keyword on its own line.
Let’s imagine that you have a single website that you want to make available to clients, such as www.mysite.com. Within your private network, you’ll have two web servers that host the files for this site. Of course, you could have many more servers than this, but for demonstration purposes, we’ll leave it at two. So that both servers can be utilized, they are load-balanced to handle the requests, meaning that they take turns receiving and responding to requests. HAProxy is a reverse proxy that sits in front of the two web servers and routes requests to them.
As we go along, you can learn more about the configuration settings by reading the official documentation. Let’s see some important directives for each section.
Global
At the top of your HAProxy configuration file is the global
section, identified by the word global
on its own line. Settings under global
define process-wide security and performance tunings that affect HAProxy at a low level.
Consider the following example:
global | |
maxconn 50000 | |
log /dev/log local0 | |
user haproxy | |
group haproxy | |
stats socket /run/haproxy/admin.sock user haproxy group haproxy mode 660 level admin | |
ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 | |
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets |
Let’s see how each of these settings works.
maxconn
The maxconn
setting limits the maximum number of connections that HAProxy will accept. Its purpose is to protect your load balancer from running out of memory. You can determine the best value for your environment by consulting the sizing guide for memory requirements.
In addition to the memory consumed by processing connections, additional memory is used by stick tables, map files, and ACL files that you’ve defined.
log
The log
setting ensures that warnings emitted during startup and issues that arise during runtime get logged to syslog. It also logs requests as they come through. You can target the traditional UNIX socket where Syslog or journald, listen, /dev/log, or specify a remote rsyslog server so that log data is preserved externally to your load balancing server. Set a Syslog facility, which is typically local0, which is a facility categorized for custom use. Note that in order to read the logs, you will need to configure any of the syslog daemons, or journald, to write them to a file.
user / group
The user
and group
lines tell HAProxy to drop privileges after initialization. Linux requires processes to be root in order to listen on ports below 1024. You’ll also typically want your TLS private keys to be readable only by root as well. Without defining a user and group to continue the process as, HAProxy will keep root privileges, which is a bad practice. Be aware that HAProxy itself does not create the user and group and so they should be created beforehand.
stats socket
The stats socket
line enables the Runtime API, which you can use to dynamically disable servers and health checks, change the load balancing weights of servers, and pull other useful levers. You can learn more by reading our blog post, Dynamic Configuration with the HAProxy Runtime API.
ssl-default-bind-ciphers
The ssl-default-bind-ciphers
setting enumerates the SSL and TLS ciphers that every bind
directive will use by default. It can be overridden with a more specific setting by adding the bind
directive’s ciphers parameter. It takes a list of cipher
suites in order of preference. HAProxy will select the first one listed that the client also supports, unless the prefer-client-ciphers
option is enabled. Try using the Qualys SSL Server Test to see how strong your chosen ciphers are and which browsers you can support.
ssl-default-bind-options
The ssl-default-bind-options
setting configures SSL/TLS options such as ssl-min-ver
to disable support for older protocols. For example, you might choose to accept only connections that use a TLS version of 1.2 or newer.
Defaults
As your configuration grows, using a defaults
section will help reduce duplication. Its settings apply to all of the frontend
and backend
sections that come after it. You’re still free to override those settings within the sections that follow.
You also aren’t limited to having just one defaults
. Subsequent defaults
sections will override those that came before and reset all options to their default values.
So, you might decide to configure a defaults
section that contains all of your TCP settings and then place your TCP-only frontend
and backend
sections after it. Then, place all of your HTTP settings in another defaults
section and follow it with your HTTP frontend
and backend
sections.
Consider this example:
defaults | |
timeout connect 10s | |
timeout client 30s | |
timeout server 30s | |
log global | |
mode http | |
option httplog | |
maxconn 3000 |
Let’s discuss what each of these settings mean.
timeout connect / timeout client / timeout server
The timeout connect
setting configures the time that HAProxy will wait for a TCP connection to a backend server to be established. The “s” suffix denotes seconds. Without any suffix, the time is assumed to be in milliseconds. The timeout client
setting measures inactivity during periods that we would expect the client to be speaking, or in other words sending TCP segments. The timeout server
setting measures inactivity when we’d expect the backend server to be speaking. When a timeout expires, the connection is closed. Having sensible timeouts reduces the risk of deadlocked processes tying up connections that could otherwise be reused.
When operating HAProxy in TCP mode, which is set with mode tcp
, timeout server
should be the same as timeout client
. That’s because HAProxy doesn’t know which side is supposed to be speaking and, since both apply all the time, having different values makes confusion more likely.
log global
The log global
setting is a way of telling each subsequent frontend
to use the log
setting that you defined in the global
section. This isn’t required for logging, as new log
lines can be added here or in each frontend
. However, in most cases wherein only one syslog server is used, this is common.
mode
The mode
setting defines whether HAProxy operates as a simple TCP proxy or if it’s able to inspect incoming traffic’s higher-level HTTP messages. The alternative to specifying mode http
is to use mode tcp
, which operates at the faster but less-aware level. If most of your frontend
and backend
sections would use the same mode, it makes sense to specify it in the defaults
section to avoid repetition.
maxconn
The maxconn
setting limits the number of connections each frontend
will accept and, by default, is set to 2000. If you want to allow more connections, you can increase it here up to your global maxconn
. On the other hand, you may wish to use a number that gives each frontend a fair share of the global connections.
option httplog
The option httplog
setting, or more rarely option tcplog
, tells HAProxy to use a more verbose log format when sending messages to Syslog. You will generally prefer option httplog
over option tcplog
in your defaults
section because when HAProxy encounters a frontend
that uses mode tcp
, it will emit a warning and downgrade it to option tcplog
anyway.
If neither is specified, then the connect log format is used, which has very few details other than the client and backend IP addresses and ports. Another option is to define a custom log format with the log-format
setting, in which case option httplog
and option tcplog
aren’t necessary.
Frontend
When you place HAProxy as a reverse proxy in front of your backend servers, a frontend
section defines the IP addresses and ports that clients can connect to. You may add as many frontend
sections as needed for exposing various websites to the Internet. Each frontend
keyword is followed by a label, such as www.mysite.com, to differentiate it from others.
Consider the following example:
frontend www.mysite.com | |
bind 10.0.0.3:80 | |
bind 10.0.0.3:443 ssl crt /etc/ssl/certs/mysite.pem | |
http-request redirect scheme https unless { ssl_fc } | |
use_backend api_servers if { path_beg /api/ } | |
default_backend web_servers |
Let’s see what these lines mean.
bind
A bind
setting assigns a listener to a given IP address and port. The IP can be omitted to bind to all IP addresses on the server, and a port can be a single port, a range, or a comma-delimited list. You’ll often use the ssl
and crt
arguments to instruct HAProxy to manage SSL/TLS terminations rather than having your web servers do that.
http-request redirect
A http-request redirect
setting responds to the client that they should try a different URL. In our example, clients that request your website over non-encrypted HTTP are redirected to the HTTPS version of the site.
use_backend
The use_backend
setting chooses a backend pool of servers to respond to incoming requests if a given condition is true. It is followed by an ACL statement, such as if path_beg /api/
, that allows HAProxy to select a specific backend based on some criteria, such as checking if the path begins with /api/. To learn more about ACLs, read our blog post Introduction to HAProxy ACLs. These lines aren’t required, and many frontend sections only have a default_backend
line and no special selection rules.
default_backend
The default_backend
setting is found in nearly every frontend
and gives the name of a backend
to send traffic to if a use_backend
rule doesn’t send it elsewhere first. If a request isn’t routed by a use_backend
or default_backend
directive, HAProxy will return a 503 Service Unavailable error.
Similar Articles:
Backend
A backend
section defines a group of servers that will be load balanced and assigned to handle requests. You’ll add a label of your choice to each backend
, such as web_servers. It’s generally pretty straightforward and you won’t often need many settings here.
Consider this example:
backend web_servers | |
balance roundrobin | |
cookie SERVERUSED insert indirect nocache | |
option httpchk HEAD / | |
default-server check maxconn 20 | |
server server1 10.0.1.3:80 cookie server1 | |
server server2 10.0.1.4:80 cookie server2 |
Let’s look at some settings you will find in a backend
section.
balance
The balance
setting controls how HAProxy will select the server to respond to the request if no persistence method overrides that selection. A persistence method might be to always send a particular client to the same server based on a cookie. Common load balancing values include roundrobin
, which just picks the next server and starts over at the top of the list again, and leastconn
, where HAProxy selects the server with the fewest active sessions.
cookie
The cookie
setting enables cookie-based persistence. It tells HAProxy to send a cookie named SERVERUSED to the client and to associate it with the server's name that gave the initial response. This causes the client to continue speaking with that server for the duration of their session. Note that the server's name is set with a cookie
argument on the server
line.
option httpchk
The option httpchk
setting causes HAProxy to send Layer 7 (HTTP) health checks instead of Layer 4 (TCP) checks to your backend servers. Servers that don’t respond are not served any more requests. Whereas TCP checks succeed if they can make a connection to the backend server’s IP and port, HTTP health checks expect to get back a successful HTTP response. Smarter health checks are instrumental in removing unresponsive servers, even if unresponsive means just getting a bad HTTP response like 500 Server Error.
By default, an HTTP health check makes a request to the root path, /, using the OPTIONS verb. However, arguments specified here can customize that. HAProxy will treat any check that gets a 2xx or 3xx response code to be successful, although this, too, can be customized with an http-check
line. Using option httpchk
isn’t restricted to backends that use mode http
, so servers that communicate using HTTP can be checked regardless of the proxying mode.
default-server
The default-server
setting configures defaults for any server
lines that follow, such as enabling health checks, max connections, etc. This can make your configuration easier to read and modify. Alternatively, you can specify these arguments on each server
.
server
The server
setting is the heart of the backend
. Its first argument is a name, followed by the IP address and port of the backend server. You can specify a domain name instead of an IP address. In that case, it will be resolved at startup or if you add a resolvers
argument, it will be updated during runtime. If the DNS entry contains an SRV record, the port and weight will be filled in from it too. If the port isn’t specified, then HAProxy will use the same port that the client connected on, which is useful for randomly used ports such as for active-mode FTP.
Although we added option httpchk
to set up HTTP-based health checking of our servers, each server must opt in to health checks by adding a check
argument. This can be set on the server
line or, as we’ve done in this example, the default-server
line.
Every server
line should have a maxconn
setting that limits the maximum number of concurrent requests that the server will be given. Even if it’s just a guess, having a value here puts you on the right foot for avoiding saturating your servers with requests and gives a baseline that can be adjusted later. In this example, we’ve set this on the default-server
line.
We introduced a new setting called server-template that can be used to create placeholder servers that a service discovery tool could then fill in with the right addresses and ports. Read about it in our blog post, What’s New in HAProxy 1.8.
What About Listen?
As you’ve seen, frontend
and backend
sections receive traffic and send it to a pool of servers. You can also use listen
sections to do the same thing. They, essentially, combine the functionality of a frontend
and backend
into one. You may prefer the readability gained by having separate frontend
and backend
sections, especially when using HTTP mode with its many options, or you may favor a more concise configuration, making listen
the preferred approach. In either case, you have the full power of HAProxy at your fingertips!
Here’s a simple example of a listen
used to serve up the HAProxy Stats page:
listen stats | |
bind *:8404 | |
stats enable | |
stats uri /monitor | |
stats refresh 5s |
Learn more about the essential sections of your usual HAProxy Configuration file in my video:
Conclusion
You’ve learned the most important sections of an HAProxy configuration file: global
, defaults
, frontend
and backend
. This will get you pretty far. After you’ve become a pro at implementing the basics, you might try setting up DNS resolution with a resolvers
section or configuring email notifications with a mailers
section. Or, you might try setting up two instances of HAProxy and exploring how a peers
section keeps them in sync.
Did you find this post helpful? What else would you like to see? Leave us a comment here or follow us on Twitter. Want to explore the advanced features available in HAProxy Enterprise? Sign up for a HAProxy Enterprise free trial or contact us to learn more.
Subscribe to our blog. Get the latest release updates, tutorials, and deep-dives from HAProxy experts.