DEV Community

Emin Vergil
Emin Vergil

Posted on • Updated on

What is HAProxy ?

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
...

Enter fullscreen mode Exit fullscreen mode
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.
Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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**
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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());
});
Enter fullscreen mode Exit fullscreen mode

3- Create package.json

You can create package.json file using the following command

npm init -y # yes to skip every question
Enter fullscreen mode Exit fullscreen mode

4- install the http library

You can install a node package using npm install command

npm i http
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

To create a docker image, use the following command:

docker build -t nodeapp .
Enter fullscreen mode Exit fullscreen mode

Dockerfile for HAProxy

FROM haproxy
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
CMD ["haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg"]
Enter fullscreen mode Exit fullscreen mode

To create a docker image, use the following command:

docker build -t haproxy .
Enter fullscreen mode Exit fullscreen mode

Test Docker images

You can test docker images using docker run command.

docker run -p 8080:8080 nodeapp
Enter fullscreen mode Exit fullscreen mode

This will run our node.js application on port 8080. You can use curl request to test the application.

curl -v localhost:8080
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Type the following command to start entire application(node.js and haproxy server):

docker compose up
Enter fullscreen mode Exit fullscreen mode

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 }
Enter fullscreen mode Exit fullscreen mode

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:

https://github.com/eminvergil/haproxy-test

Top comments (0)