Dockerizing a Node and MongoDB application
Hello everyone, I’m going to show you how to containerize an app using Docker including Docker-compose. I have already created a simple Node application which is an Express server connected with MongoDB. Here’s the git repo. I’m going to explain the process using this project. So it’s better if you clone this project.
Project work-through
In this project, I have created a server and defines some API routes to test the application. You can found them on /routes/api.js. The following image shows the database connection.
And if we look into the /config/mongodb.js (above picture), the URI to connect to MongoDB is little bit different. You’ll notice that I haven’t use the localhost here. If we connect to the local MongoDB database we use the localhost, instead, I have used “mongo” because “mongo” is going to be our service. We are going to create a separate docker container for MongoDB and I’m going to name it as “mongo”. You’ll understand this later 😉
Dockerfile
To containerize this project, we have to create the Dockerfile. You can already see this on the project’s root. This file’s name is “Dockerfile” with no extension.
First, we define (line 2) the image that we are going to use as FROM node:12
node is the image name and :12 tag means, we are going to use the latest release of node version 12. If we haven’t the image Docker will pull it from Docker Hub.
Then we create a working directory (line 5) by WORKDIR /usr/src/app
command. Basically, we define where our app lives in the container.
Then we should copy package.json into our container (line 8) to install the dependencies. COPY package*.json ./
Here * is a wild card, so it’ll copy the package.json and package-lock.json into the container.
And RUN npm install
will install the dependencies by running the command (line 11). Then we need to copy everything else (line 14). It’ll do by the COPY . .
command.
EXPOSE 5000
command exposes the port that the application runs on (line 17). And finally, the command CMD [“npm”, “start”]
(line 20). I already wrote a start script in package.json. So, it’ll run the application.
Yes, we can build this now, but the app is going to look for MongoDB. So, it’s not going to work yet. We can manually create another container for mongo, but we are no doing it that way. We want this to easily port to another system and docker-compose allows us to do that.
docker-compose.yml
Let’s create the docker-compose.yml file (docker-compose is used to run multiple containers). It keeps the information about the Docker commands we need to run. So, we don’t need to manually run each command.
I have added two services app and mongo. They are just names and I have defined container names for each service. If you remember earlier I showed that I used “mongo” instead of “localhost” in MongoDB connection. The reason is to map it to this service named as mongo.
In app service, restart: always
means it’ll restart if it fails. Then the image, we need it to build from our Dockerfile. It’ll do by build: .
line, by looking for a Dockefile in the current directory. Next, we map the ports. Line 8, 9 maps the port 80 in our local machine to port 5000 in the container.
In mongo service, I have defined the image as mongo because we not going to build it from our Dockerfile. So, we can pull the mongo image from Docker Hub by defining it here. Like app service, we map the ports in mongo container as well. And finally, we have to link our two containers. It’ll do by lines 10 and 11.
.dockerignore
.dockerignore file marks the files which should ignore when we pushing the image. it should be in the same directory as your Dockerfile. We can add node_modules, npm-debug.log so, it will prevent your local modules and debug logs from being copied onto your Docker image and possibly overwriting modules installed within your image.
Running two containers
Now in the terminal run the command docker-compose up
. It’s going to pull mongo and Node 12 images from Docker Hub and do everything on Dockerfile. Also, creates the containers and after the build is finished you can see the console.log messages on the console.
To test our app, open the Postman. Then send a POST request to localhost/api endpoint as the following image.
We don’t need to use localhost:5000/api because in the docker-compose file we mapped port 5000 in the container to port 80 in our local machine. If two containers working perfectly you’ll get the response with 200 status code.
Also, by sending a GET request to localhost/api, we can get all the records we added to MongoDB.
Also, you can run the command docker ps
on the terminal to list the running containers. So, that’s it for today. Hope you learn something from my article. Feel free to respond.
Happy Coding Folks 👽