Dockerizing a NodeJS and MongoDB App — A tale of Docker and Containers

Yashvardhan Kukreja
7 min readDec 10, 2018

Introduction

Let’s assume that you are building an application which is written in both Python and Java. Now, to execute your application on a machine, specific versions of Python and Java are required. So, what if your team member wants to execute your application on their machine. Clearly, he/she would have to install those required specific versions of Python and Java. And eventually, on trying to install those versions, there will be version conflicts due to the preexisting versions of Java and Python in that team member’s system which can mess up things.

This is a small example of a small problem but the intensity of this kind of problem increases when a real time application with a lot of frameworks, languages, etc. is dealt with.

So, what’s the solution?

Enter the DOCKER!!

Image result for docker and nodejs
https://cdn-images-1.medium.com/max/1354/1*GG896wAv82dpcXlSXJN2Jg.jpeg

What is Docker?

Docker is a containerization platform on which you build your applications and package them along with their dependencies (frameworks/language versions) into containers and then, these containers can be easily and efficiently shipped to other machines for easily executing that applications.

With me? Cool!

But what “are” containers?

I explain that by explaining about virtualisation followed by containerization.

So, virtualisation was introduced some/a lot (Idk!) years ago. It, basically, involved running multiple guest operating systems (virtual machines) on top of a host machine. So, this technique eliminated the need for extra hardware.

But guess what, it had its shortcomings too. Running multiple OS on a host machine can degrade its performance massively by taking up a large chunk of resources like RAM, disk space, etc.

So, to sort this out, Containerization was introduced.

Containerization is a method which brings virtualization to host’s operating system level. It doesn’t involve the creation of whole new guest OS’s. It directly gets attached at the OS level and shares relevant libraries with the host OS when required, unlike virtual machines.

So, these containers are wayyyy lighter and faster than virtual machines. Their bootup process is even very short.

So, in simple words,

Virtualisation involves virtual machines

Containerization involves containers

The image below clearly depicts the difference between containerization and virtualisation (Don’t get baffled with the weird terms below, just understand the basic visual difference between them)

https://qph.fs.quoracdn.net/main-qimg-0f8f2382c4a7837a0a81b0f6ab79ebab

Let’s dockerize our NodeJS and MongoDB app

Before proceeding, I strongly recommend you guys to get a very basic idea about NodeJS.

I have written a simple article for that here. We will be using that basic NodeJS App in that article only and dockerize it.

Our app

So, below is the code for app which

And this is directory structure which will be involved in this app

So, we are going to be dealing with three files

  • dockerfile — It will involve a set of commands which will be executed so as to prepare our app for dockerization
  • docker-compose.yml — It will involve some lines of code which will be responsible for executing our dockerized app in an easy and short way
  • .dockerignore — Involves the folders to be ignored while dockerization takes place

dockerfile

Here is the screenshot of the dockerfile

I’ll explain this line by line

  • The first line specifies which image and which version of it should the container be built from. In our case, we are going to build our container from “node” image and the version of that image is gonna be “10”
  • The second line creates a directory (/usr/src/app) in the image
  • The third line specifies that directory to be used as the working directory where the whole application will be stored. So, after this, our current directory will be “/usr/src/app”
  • The fourth line copies “package.json” and “package-lock.json” into the current directory “./”
  • The fifth line executes/RUNs the command, “npm install”. So, when this command runs, the “npm” looks into package.json and installs all the dependencies written in there and thereby stores them in a new folder named “node_modules”, just like what happens generally.
  • The sixth line bundles the app’s source code to our current docker image.
  • The seventh line exposes our app to port number 8080. So, our dockerized app will run on port number 8080
  • The last line executes the command “npm start” which basically corresponds to “node index.js” and hence, our dockerized server will be started.

.dockerignore

This file will prevent the local modules and debug logs to get copied to the image and overwrite modules within the image.

docker-compose.yml

Now, we are going to create multiple containers, two in this case. One for running our server and the other one for running the database.

This file will configure and link different container services and help us eradicate the need of building and executing a big command to run our docker image everytime.

Chill! I’ll explain this line by line as well.

  • The first line specifies the version of docker compose we are using. It’s best to go with “3”
  • The second line corresponds to the services (multiple containers) and along with their details.
  • In the third line, we declare our first service as “app” which will execute that “dockerfile” and which in turn will run our server.
  • In the fourth line, we specify the container name for the service “app” as “first_proj”. (You can give any other name)
  • The fifth line makes sure that the service “app” restart always as soon as it crashes instead of just stopping abruptly.
  • The sixth line tells to build the service “app” by running the whole dockerfile (by specifying “.”)
  • The seventh line corresponds to specifying the mapping of ports.
  • The eighth line maps this container’s port number “8080” to the machine’s port number “8000” (Note that our app is exposed to 8000). Hence, on running our dockerized server, our app will run on port number 8080 instead of 8000 because then, it is going to be the container on which the server is going to be running.
  • The ninth line corresponds to specifying the links to which the current service “app” (our server) will link.
  • The tenth line tells the service “app” to link with the service named “mongo” (the service which will correspond to the container associated with our mongo database)
  • Now, we will be declaring the other service which will correspond to the container associated with the MongoDB
  • The eleventh line does that under the service named “mongo”.
  • The twelfth line specifies the container name (“mongo” , it can be different) for the container in which this service will run.
  • The thirteenth line specifies the image (mongo) over which this service will run.
  • The fourteenth line maps this container’s port number 27018 with the default MongoDB port number of the machine i.e. 27017. On running our app, the database will run on 27018 instead of 27017 because our app will be running the above containers.

Let’s execute Stuff

Run the following command (in the same project directory which contains the above three files) for building.

docker-compose build
The terminal output after executing the above command

The above command needs to be executed just once.

Now, whenever you want to run your dockerized app, just execute the command below

docker-compose up
The terminal output after executing the above command

Output

On entering “localhost:8080/homepage” in the browser’s search bar

So, our app is successfully running on port number 8080

Final Note

Congratulations on creating your first NodeJS dockerized app :D

Thank you for reaching till here. If you liked this article, do give me some claps XD.

I hope you understood everything about this article. Still, if you face any problem/doubt regarding this article or life XD, feel totally free to contact me.

E-mail — yash.kukreja.98@gmail.com

Github — https://github.com/yashvardhan-kukreja

LinkedIn — https://www.linkedin.com/in/yashvardhan-kukreja-607b24142/

--

--

Yashvardhan Kukreja

Software Engineer @ Red Hat | Masters @ University of Waterloo | Contributing to Openshift Backend and cloud-native OSS