Dockerize the NodeJS app

0
843
lessons learned from prometheus

Containerization is the most important aspect to bundle all the dependencies together we called it as container. Container can be an application container, web container or a database container. The advantage of the containerization is to run app anywhere regardless the dependencies because container bundle it with Images. Container engine is used for communication between containers and underlying kernel of Operating System. Docker is the most popular container engine. There are other container engines like rkt, lxc. 

To containerize the application with Docker set of instructions to be written. Dockerfile consists all these instructions.
Here we will use sample NodeJs application. The structure of the basic app will be: 

app/
— server.js
— package.json

server.js:

const express = require(‘express’);

const app = express();

app.get(‘/’, function (req, res) {
    res.send(‘Hello World!’);
});

app.listen(3000, function () {
    console.log(‘Example app listening on port 3000!’);
});

Package.json:

{
  “name”: “hello-world”,
  “version”: “1.0.0”,
  “description”: “Hello world app taken from: https://expressjs.com/en/starter/hello-world.html”,
  “main”: “server.js”,
  “scripts”: {
    “test”: “”,
    “start”: “”
  },
  “repository”: {
    “type”: “git”,
    “url”: “git+https://github.com/borderguru/hello-world.git”
  },
  “author”: “”,
  “license”: “ISC”,
  “bugs”: {
    “url”: “https://github.com/borderguru/hello-world/issues”
  },
  “homepage”: “https://github.com/borderguru/hello-world#readme”,
  “dependencies”: {
    “chai”: “^4.1.2”,
    “express”: “^4.15.3”,
    “mocha”: “^4.0.1”,
    “request”: “^2.83.0”
  }
}

To Dockerize the app, we need to create the Dockerfile: 

Dockerfile:

# The official image of the node
FROM node:boron
# ARG Version to define app version
ARG VERSION=1.0.0

# Create app directory inside image
WORKDIR /usr/src/app

# Set required environment variables
ENV NODE_ENV production

# Install app dependencies by copying package.json to image
COPY package.json .

# For [email protected] or later, copy package-lock.json as well
# COPY package.json package-lock.json ./

RUN npm install

# Bundle app source
COPY . .
# It will start the app on 3000 port of the container
EXPOSE 3000
CMD [ “npm”, “start” ]

This is well defined dockerfile. Make sure docker should be pre-installed on machine. If it is not installed then, install via official documentation of the docker. 

The Dockerfile consists set of commands which includes making work directory where necessary files will be copied. Installing dependencies using npm.  Note the base image node:boron is official image from NodeJS and it consists stable npm version. After copying all files and installing dependencies exposing 3000 port of the container and first command will run npm start. 

This is sample Dockerfile but it is not limited with just given commands. For more in depth information please check official guide of the Docker for creating Dockerfile. 

To create the images from the Dockerfile docker cli is used. Now the app structure is:

app/
— server.js
— package.json
— Dockerfile 

Run the following command:

$ sudo docker build -t helloworld:1.0 .

It will build the image and tag it with helloworld:1.0 here 1.0 is the version of image. If nothing is specified then, the latest version will be chosen. 

This will download all dependencies to run the app. After successful build, check the images.

$ sudo docker images
REPOSITORY          TAG IMAGE ID            CREATED SIZE
helloworld          1.0 c812ebca7a95        About a minute ago 678 MB
node                boron c0cea7b613ca        11 days ago 661 MB

To run the container docker run command is used. It’s necessary to bind the  node port to container port. 

$ sudo docker run -it -p 3000:3000 helloworld:1.0

Here its binding port 3000 to container port 3000. 

Check if app is running:

$ curl localhost:3000
Hello World!

Tag the image and push to dockerhub:

$ sudo docker images
REPOSITORY          TAG IMAGE ID            CREATED SIZE
helloworld          1.0 c812ebca7a95        3 hours ago 678 MB
node                boron c0cea7b613ca        11 days ago 661 MB
$ sudo docker tag helloworld:1.0 helloworld:latest
$ sudo docker images
REPOSITORY          TAG IMAGE ID            CREATED SIZE
helloworld          1.0 c812ebca7a95        3 hours ago 678 MB
helloworld          latest c812ebca7a95        3 hours ago 678 MB
node                boron c0cea7b613ca        11 days ago 661 MB

Tagging image to latest to indicate this will be the most recent version of the image.  Dockerhub is the central registry for storing docker images. However, there are many other registries available like JFROG, Quay and Amazon ECR. 

Login to dockerhub: 

(Notice: If you don’t know dockerhub then please visit https://hub.docker.com and create account)

$ sudo docker login with your Docker ID to push and pull images from Docker Hub. If you don’t have a Docker ID, head over to https://hub.docker.com to create one.
Username (kubejack): kubejack
Password:
Login Succeeded

$ sudo docker tag helloworld:latest kubejack/helloworld:latest
$ sudo docker push kubejack/helloworld:latest
The push refers to a repository [docker.io/kubejack/helloworld]
50c9a7dd83b6: Pushed
94df5aea4989: Pushed
e7158264ab54: Pushed
54e9e4999177: Pushed
7c966bc7c94e: Mounted from library/node
c3031c131aac: Mounted from library/node
7df250eb9e5c: Mounted from library/node
e9591a63b7e4: Mounted from library/node
d752a0310ee4: Mounted from library/node
db64edce4b5b: Mounted from library/node
d5d60fc34309: Mounted from library/node
c01c63c6823d: Mounted from library/node
latest: digest: sha256:952ff7e89547e157630be120126a3e1d8717d45e0df72a1f49901c2bcde74250 size: 2838

The image is pushed now and now you can run the app from anywhere with Docker.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments