Dockerizing ExpressJS Application with NGINX Balancing

Mohammad Al Kalaleeb
2 min readApr 26, 2020

in this tutorials we are going to Dockerize a Hello Word Express Application.

Preparing the project

we start by making a new folder and moving into it

mkdir dockerized_express
cd dockerized_express

now that we got this out of the way we can start by opening our code editor; i use VS Code, so, deal with it :)

we create a folder called api and in it we can create our Hello World server.

first we create a node project by using

yarn --init # I use Yarn, Just because
npm --init # You can use that, its free you know

then we add express dependency

yarn add express
# OR
npm i express

Preparing the API

so in order to do that we should create a file names app.js containing

'use strict';

const express = require('express');

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
res.send('Hello World From ' + process.env.INSTANCE); // This will be usefull later
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

Creating the Docker File and Docker Ignore

in .dockerfile we write

FROM node:lts-alpine3.9
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app

COPY package*.json ./
USER node
RUN npm install

COPY --chown=node:node . .

EXPOSE 8080

CMD [ "node", "app.js" ]

and in .dockerignore we can write

node_modules
npm-debug.log

Nginx

we should create our Nginx docker build file first, I created it in .docker folder, and i wrote in it:

FROM nginx:stable-alpine

COPY ./nginx.conf /etc/nginx/nginx.conf

EXPOSE 8080

beside that, and in the same folder I wrote

worker_processes 4;

events { worker_connections 1024; }

http {
upstream api {
server api_01:8080 weight=1 max_fails=3 fail_timeout=30s;
server api_02:8080 weight=1 max_fails=3 fail_timeout=30s;
server api_03:8080 weight=1 max_fails=3 fail_timeout=30s;
}

server {
listen 80;

location / {
proxy_pass http://api;
}
}
}

Note that upstream is the balancing line, and we have but a single route, as this is a tutorial on dockerizing.

Creating the Compose File

I love compose files, they provide the most usefulness and customizability, our case here require something like

version: '3'

services:
web:
build:
context: .
dockerfile: .docker/nginx.dockerfile
container_name: nginx
links:
- api_01:api_01
- api_02:api_02
- api_03:api_03
depends_on:
- api_01
- api_02
- api_03
ports:
- 80:80
networks:
- app-network


api_01:
build:
context: ./api
dockerfile: Dockerfile
container_name: api_01
networks:
- app-network
environment:
- INSTANCE=SERVER_01

api_02:
build:
context: ./api
dockerfile: Dockerfile
container_name: api_02
networks:
- app-network
environment:
- INSTANCE=SERVER_02

api_03:
build:
context: ./api
dockerfile: Dockerfile
container_name: api_03
networks:
- app-network
environment:
- INSTANCE=SERVER_03

networks:
app-network:
driver: bridge

Great, Now we can run this small application using:

docker-compose build
docker-compose up -d

and voilà, once you visit the localhost you shall find the Hello World message followed by the instance name we provided via the docker-compose file.

C U Later and Good Luck

--

--

Mohammad Al Kalaleeb

Android to the core, AI and Machine Learning Enthusiast.