
This assumes you have installed HAProxy and have configured HAProxy to load balance a single websites across two or more web servers.
Let's say the servers www1.example.com and www2.example.com are producing the www.example.com and stage.example.com domains.
Listen Block
One option would be to have multple listen blocks.
AVOID TROUBLE
The www.example.com and stage.example.com domains would have to be listening on different ports, to avoid a port conflict situation on HAProxy.
Each listen block will need a unique "bind" port.
listen www
bind *:80
mode tcp
balance roundrobin
server www1 www1.example.com:80 check
server www2 www2.example.com:80 check
listen stage
bind *:81
mode tcp
balance roundrobin
server stage1 www1.example.com:18080 check
server stage2 www2.example.com:18080 check
If you have a firewall, such as iptables or firewalld, you will need to allow the HAProxy bind port, not the ports being used by the "server" directives. In this example, only the http (port 80) service would need to be allowed.
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
firewall-cmd --reload
Frontend / Backend
Let's say www.example.com and stage.example.com are both listening on ports 80 and 443. In this situation, the frontend and backend blocks can be used.
A significant advantage is that the frontend can be listening on a single port, such as 80, and each backend can have a unique port.
hdr is short for HTTP headers. For example, the curl command can be used to see the "host" header.
~]$ curl http://www.freekb.net --verbose
> GET / HTTP/1.1
> Host: www.freekb.net
> User-Agent: curl/7.79.1
> Accept: */*
Or if running a Python app (e.g. Django or Flask), you might do something like this to get the headers.
@views.route('/')
def home():
print(request.headers)
return render_template('home.html')
In this example, acl www hdr(host) -i <HTTP header host> is used to route requests to different backends based on the HTTP host header. The -i flag means case insensitive. It's important to recogize that this looks for an exact match. For example, if you have acl www hdr(host) -i www.example.com but the Host Header is "example.com" this will not match, thus the default backend would be used.
frontend main
bind *:80
bind *:443 ssl crt /etc/pki/tls/foo.pem
balance roundrobin
acl www hdr(host) -i www.example.com
use_backend www_example_com if www
acl stage hdr(host) -i stage.example.com
use_backend stage_example_com if stage
default_backend www_example_com
backend www_example_com
server www1 www1.example.com:80 check
server www2 www2.example.com:80 check
backend stage_example_com
server stage1 www1.example.com:18080 check
server stage2 www2.example.com:18080 check
Let's say you have a few different domains that contain "foo", perhaps something like this.
- www.foo.com
- www.foo.link
- stage.foo.com
In this scenario, you may want to use the -m reg option to use a regular expression to match "foo".
acl foo hdr(host) -m reg -i .*foo.*
use_backend foo if foo
Did you find this article helpful?
If so, consider buying me a coffee over at