🚀 Running a Node.js Web App Using Docker: A DevOps Guide

👋 Introduction

In today's DevOps task, we'll explore how to deploy a Node.js web application using Docker. Docker simplifies deployment by packaging applications and their dependencies into containers, ensuring consistency across various environments. We'll begin by setting up the prerequisites, including Git and Docker. Our goal is to provide a step-by-step walkthrough, from creating a Dockerfile to running the Node.js app within a Docker container. By the end of this guide, you'll have a foundational understanding of using Docker for efficient application deployment in a DevOps context.

📌Pre-requisite

  • Git is installed and configured to your GitHub account.

  • Docker is installed.

    Follow the below steps to install and configure docker.

      ubuntu@~$: sudo apt update
      ubuntu@~$: sudo apt upgrade
    
      #install docker.io package
      ubuntu@~$: sudo apt install docker.io
    
      #check the version of docker
      ubuntu@~$: docker -v
      Docker version 20.10.25, build 20.10.25-0ubuntu1~22.04.2
    
      #check the status of docker service. It should be active (running)
      ubuntu@~$: systemctl status docker
    

    Once the above steps are done, test the first docker command docker ps

      ubuntu@~$: docker ps
      Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
    

    You will witness permission denied error. This is because the current logged-in user ubuntu is not part of the docker group. To provide access, we need to add ubuntu to the docker group. Restart the docker service and if required reboot the system. Then try.

      ubuntu@~$: sudo usermod -aG docker $USER
      ubuntu@~$: sudo systemctl restart docker
      ubuntu@~$: docker ps
      Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
    
      #since we got the error again, we need to reboot the system
      ubuntu@~$: sudo reboot
    
      #after system reboot
      ubuntu@~$: docker ps
      CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    

    Now that we can run the docker command, we are ready to start using docker.

  • Basic knowledge of git and docker commands.

💡Task: Running a Node.js App using Docker

👣Step 1: Fork and clone GitHub repository

We will be using the Nodejs web app on my GitHub repository at https://github.com/pka2412/DevOps.git to run using docker. The web app is available under docker/nodejs folder. The web app uses ExpressJS framework.

Fork the repository to your GitHub account and clone it to your local system.

👣Step 2: Create Dockerfile

Create a Dockerfile to create image for the nodejs web app.

#get the nodejs base image from docker-hub or locally
FROM node:alpine3.17

#set the working directory inside the container
WORKDIR app

#copy the contents of host current directory to the container current directory
COPY . .

#initialize node app and install express, ejs packages
RUN npm init -y \
 && npm install express \
 && npm install ejs

#expose the 3000 port to access the web-app
EXPOSE 3000

#start the web-app
CMD ["node","index.js"]

👣Step 3: Create docker image

After creating the Dockerfile we use docker build command to create the nodejs-web-app image.

#create nodejs-web-app image
ubuntu@~/DevOps/docker/nodejs/nodejs-web-app
$ docker build . -t nodejs-web-app

#output
Sending build context to Docker daemon  6.144kB
Step 1/6 : FROM node:alpine3.17
alpine3.17: Pulling from library/node
9398808236ff: Pull complete
822c4812cd6a: Pull complete
9d4f6912d8ff: Pull complete
bbb51eba7fa3: Pull complete
Digest: sha256:c8ae1785da54b802347d06e826d5ae127fc7851114803ee4098f782d46ba40a9
Status: Downloaded newer image for node:alpine3.17
 ---> fd558fad007f
Step 2/6 : WORKDIR app
 ---> Running in 6d8f18b07db8
Removing intermediate container 6d8f18b07db8
 ---> d62255e92e41
Step 3/6 : COPY . .
 ---> b40425ac23cd
Step 4/6 : RUN npm init -y  && npm install express  && npm install ejs
 ---> Running in 514687fcbb0a
Wrote to /app/package.json:

{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

added 58 packages, and audited 59 packages in 2s

8 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice
npm notice New patch version of npm available! 9.8.0 -> 9.8.1
npm notice Changelog: <https://github.com/npm/cli/releases/tag/v9.8.1>
npm notice Run `npm install -g npm@9.8.1` to update!
npm notice

added 16 packages, and audited 75 packages in 2s

10 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Removing intermediate container 514687fcbb0a
 ---> c5c9fbf81e58
Step 5/6 : EXPOSE 3000
 ---> Running in 81d1f7bbe20b
Removing intermediate container 81d1f7bbe20b
 ---> 27d7dfc906b3
Step 6/6 : CMD ["node","index.js"]
 ---> Running in ba5b1d99ba7f
Removing intermediate container ba5b1d99ba7f
 ---> 575e4ac9acf3
Successfully built 575e4ac9acf3
Successfully tagged nodejs-web-app:latest
#check whether the image nodejs-web-app is created
ubuntu@~/DevOps/docker/nodejs/nodejs-web-app
$ docker images
REPOSITORY       TAG          IMAGE ID       CREATED         SIZE
nodejs-web-app   latest       575e4ac9acf3   3 minutes ago   189MB
node             alpine3.17   fd558fad007f   2 weeks ago     180MB

👣Step 4: Run the docker image

Now, that the nodejs-web-app image is ready, we use docker run command to run the container and hence start running the nodejs web app.

ubuntu@~/DevOps/docker/nodejs/nodejs-web-app
$ docker run -d -p 3000:3000 nodejs-web-app
4ffafc988dd7df4b28d1e8b3f217603cefe209c85f626618886de869d7447c8a

#check whether the nodejs-web-app container is running
ubuntu@~/DevOps/docker/nodejs/nodejs-web-app
$ docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED              STATUS              PORTS                                       NAMES
4ffafc988dd7   nodejs-web-app   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:3000->3000/tcp, :::3000->3000/tcp   epic_robinson

NOTE: If you are using AWS EC2 instance then make sure you have added a new inbound rule for port 3000.

Now to test how the web app is running at port 3000.

🔚Conclusion

Congratulations, you've successfully navigated the process of deploying a Node.js web application using Docker! 🎉 Embracing containerization not only streamlines your deployment but also ensures consistency and reliability across different environments.

By following the steps outlined in this guide – from setting up prerequisites, creating a Dockerfile 📄, to running your app in a Docker container 🐳 – you've gained hands-on experience in integrating Docker into your DevOps workflow. This knowledge opens doors to faster, more efficient application deployment and management.

"🌱 Keep learning, and spread the knowledge to inspire others. 🚀💡"