Dockerizing a Node Js web app

Posted By :Harish Dhakad |11th July 2022


Dockerizing a Node.js web app


This blog aims to demonstrate how to instal a Node.js application within a Docker container. This blog is not meant to be deployed in production; instead, it is meant for development. This manual also assumes you know the basics of how a Node.js application is put together, and you have a functioning Docker installation.


A container is a "box or bucket" that Docker gives you the ability to pack an application into together with its environment and all of its dependencies. Usually, a container consists of an application running in a particular environment of a Linux operating system. A container is a running instance of an image, while an image is the blueprint for a container.


Creating a Dockerfile


Create a blank file with the name Dockerfile:


$touch Dockerfile


Open the Dockerfile in your favorite text editor {I use nano editor}


The first thing we need to do is define from which image we want to build. The most recent LTS (long-term support) version 16 of a node is used in this article and is accessible from the Docker Hub:


FROM node:16


Next, we create a directory to copy the application code inside the image, this will be the working directory for our application:

# Create an app directory


WORKDIR /usr/src/app


This image comes with Node.js and NPM already installed in it so the next thing we need to do is to install our app dependencies using the npm binary so that there is all dependencies are installed. Please be aware that a package-lock.json file won't be generated if you are using npm version 4 or earlier.


# Install app dependencies

# A wildcard is used to make sure both package.json AND package-lock.json are copied.

# where available (npm@5+)


COPY package*.json ./


RUN npm install

# If we are building our code for production

# RUN npm ci --only=production


Note that, we are only copying the package.json file and not the working directory as a whole. This enables us to utilize cached Docker layers.  Furthermore, the npm ci command, specified in the comments, helps provide faster, more reliable, reproducible builds for production environments. You can read more details about this here.


Use the COPY command to transfer the source code for our app inside the Docker image:


# Bundle app source




Our app now binds to port 8080 so we have used the EXPOSE instruction to have it mapped by the docker daemon:




Last but not least, we will use CMD, which defines our runtime, to define the command that runs our application. Here, we'll launch our server using node server.js:


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


Our Dockerfile should now look like this once we collect all commands:


FROM node:16


# Create an app directory

WORKDIR /usr/src/app


# Install app dependencies

# A wildcard is used to make sure both package.json AND package-lock.json are copied

# where available (npm@5+)


COPY package*.json ./


RUN npm install

# If we are building your code for production

# RUN npm ci --only=production

# Bundle app source




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


.dockerignore file

Create a .dockerignore file in the same directory as our Dockerfile is situated with the following content in it:





This will prevent our local node modules and npm debug logs from being copied onto our Docker image and prevent overwriting the modules installed within your image.


Building Our image

Go to the directory in which our Dockerfile is located and run the following command to build the Docker image. The -t flag lets us tag our image so it's easier to get the image later using the docker images command:


docker build. -t <your username>/node-web-app

Our image will now be listed by Docker using :


$ docker images


# Example

REPOSITORY                      TAG        ID              CREATED

node                            16         3b66eb585643    5 days ago

<your username>/node-web-app    latest     d64d3505b0d2    1 minute ago


Run the image


Running our image with -d  will run the container in a detached mode which leaves our container running in the background. A public port is redirected and mapped to a private port inside the container using the -p flag. Run the image which we have previously built:


docker run -p 3000:8080 -d <your username>/node-web-app


Print the output of our app:

# To get all running containers with container ID

$ docker ps


# Print logs of a container

$ docker logs <container id>


# Example

Running on http://localhost:8080


If we need to go inside the container we have to use the exec command:


# Enter into container using: 

$ docker exec -it <container id> /bin/bash




To test the app, get the port of our app that Docker is mapped with:


$ docker ps


# Example

ID            IMAGE                                COMMAND    ...   PORTS

ecce33b30ebf  <your username>/node-web-app:latest  npm start  ...   49160->8080


In the example above, The 8080 port inside the container was mapped by Docker to port 49160 on your computer.

You can now use curl to call your application ( if necessary, install curl using sudo apt-get install curl):


$ curl -i localhost:3000


HTTP/1.1 200 OK

X-Powered-By: Express

Content-Type: text/HTML; charset=utf-8

Content-Length: 12

ETag: W/"c-M6tWOb/Y57lesdjQuHeB1P/qTV0"

Date: Mon, 13 Nov 2017 20:53:59 GMT

Connection: keep-alive

Hello world 3 baar


Shut down the image


To close the app we started, In docker, we run the kill command. The kill command uses the container's ID.


# Stop the running container

$ docker kill <container id>

<container id>


Now check that the app has stopped or running 


$ curl -i localhost:3000


Curl: (7) Connection to localhost port 3000 was unsuccessful: Connection refused.


I hope this blog helped you regarding how to deploy and run a simple Node.js application on Docker.


About Author

Harish Dhakad

Harish Dhakad has very good knowledge in the field of Devops. His expertise are in kubernets and Linux. He is energetic and enthusiastic about his work.

Request For Proposal

[contact-form-7 404 "Not Found"]

Ready to innovate ? Let's get in touch

Chat With Us