- Published on
What is HAProxy ?
- Authors
- Name
- Emin Vergil
- @eminvergil
Target Audience
I've aimed this article at people who want to learn about HAProxy, Docker, Containers, Node.js.
Learning Objectives
After completing this article, you will know how to do the following:
- Create a simple node.js application and docker image for it.
- Create and setup HAProxy configuration and docker image for it
- Setup
docker-compose.yml
configuration. - Use docker compose to start the entire application.
- Make API calls to test the HAProxy.
What is HAProxy ?
Wiki Definition
HAProxy is a free and open source software that provides a high availability load balancer and reverse proxy for TCP and HTTP-based applications that spreads requests across multiple servers.It is written in C and has a reputation for being fast and efficient (in terms of processor and memory usage). src
Configuration
Frontend
When HAProxy is used as a reverse proxy in front of 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 to expose various websites or applications to the internet. src
# haproxy.cfg file
frontend myapp
mode http # proxy mode --> http(layer 7), tcp(layer 4)
bind *:80 # listen all ip adresses with port number 80
default_backend myserver # default pool of backend servers
...
The "mode" of the "backend" section that receives traffic from a "frontend" section should be the same. The configuration won't work if there's a mismatch.
Backend
HAProxy frontend sections accept incoming connections that can then be forwarded to a pool of servers. The backend
section is where those pools of servers that will service requests are defined.src
# haproxy.cfg file
#backend section
backend myserver
mode http # mode has to be same as frontend
server s1 localhost:11
server s2 localhost:22
server s3 localhost:33
Health Checking
HAProxy keeps only healthy servers in the load-balancing rotation. It checks the status of each server by using one of the health checking modes described in this section.
You can see the example configuration for health check below:
backend myserver
mode http
option httpchk # enable http health check
server s1 localhost:80 check
server s2 localhost:81 check
server s3 localhost:82 check
Timeout
If you’re unsure as to what it means, it’s simple: when hitting a timeout, your first reaction should not be to increase the timeout. You should investigate why something is taking so long that you hit a timeout somewhere and fix the root cause
You can check out the basic HAProxy timeouts in the table below:
name | explanation |
---|---|
timeout client | Set the maximum inactivity time on the client side. |
timeout connect | Set the maximum time to wait for a connection attempt to a server to succeed. |
timeout server | Set the maximum inactivity time on the server side. |
Configuration file for this demo
We will use this configuration for demo.
defaults
mode http
timeout client 10s
timeout server 10s
frontend f
bind *:80
default_backend servers
backend b
server s1 127.0.0.1:1111
server s2 127.0.0.1:2222
server s3 127.0.0.1:2222
Creating simple HTTP server
We will create a simple HTTP web sever using node.js and http library.
Take the following steps to create node.js application: 1- create app folder 2- create index.js file and copy & paste the following code
index.js
file:
const http = require('http')
const defaultPort = 1111
const portNumber = process.env.PORT || defaultPort
const httpServer = http.createServer((req, res) => {
res.statusCode = 200
res.end('Hi, listening on port: ' + portNumber)
})
httpServer.listen(portNumber, '0.0.0.0', () => {
console.log(httpServer.address())
})
3- Create package.json
You can create package.json
file using the following command
npm init -y # yes to skip every question
4- install the http
library
You can install a node package using npm install
command
npm i http
Dockerfile for HAProxy and Node.js App
We will use docker to run HAProxy and Node.js servers, and we will test our application using simple HTTP requests.
Dockerfile for Node App
You can copy & paste the following snippet to create a docker image for node.js application.
FROM node:13
WORKDIR /home/node/app
COPY app /home/node/app
RUN npm install
CMD npm run app
To create a docker image, use the following command:
docker build -t nodeapp .
Dockerfile for HAProxy
FROM haproxy
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
CMD ["haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg"]
To create a docker image, use the following command:
docker build -t haproxy .
Test Docker images
You can test docker images using docker run
command.
docker run -p 8080:8080 nodeapp
This will run our node.js application on port 8080. You can use curl
request to test the application.
curl -v localhost:8080
Docker compose
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application's services. src
#docker-compose.yml
version: "3"
services:
app1:
image: app
environment:
- PORT=1111
ports:
- "1111:1111"
app2:
image: app
environment:
- PORT=2222
ports:
- "2222:2222"
app3:
image: app
environment:
- PORT=3333
ports:
- "3333:3333"
haproxy:
image: haproxy
ports:
- "80:80"
volumes:
- ./haproxy:/usr/local/etc/haproxy
Type the following command to start entire application(node.js and haproxy server):
docker compose up
This will run the entire application, and now you can test the application making simple HTTP requests. HAProxy by default use round-robin algorithm to handle which servers will be selected when requests come.
Example logs in docker:
haproxy_test-app1-1 | { address: '0.0.0.0', family: 'IPv4', port: 1111 }
haproxy_test-app3-1 | { address: '0.0.0.0', family: 'IPv4', port: 3333 }
haproxy_test-app2-1 | { address: '0.0.0.0', family: 'IPv4', port: 2222 }
As you can see, we can see that our three node.js applications started, and we can make request.
You can see the codes here: