# How to Deploy a Node.js App with Jenkins CICD and Docker Compose | Day 24 of 90 Days of DevOps

Hello, everyone!

I hope you are enjoying your DevOps journey with 90DaysOfDevops. Today, I will show you how to deploy a Node.js todo app with Jenkins and Docker Compose.

## What is the Node.js Todo App?

The Node.js todo app that I will use for this tutorial is a simple todo app that allows users to create, read, update, and delete tasks. The app uses Express as the web framework and EJS as the templating engine.

The source code for the app is available on GitHub: [https://github.com/ajitfawade/node-todo-cicd.git](https://github.com/ajitfawade/node-todo-cicd.git)

The app has two main files:

* `app.js`: The main entry point of the app that sets up the Express server, the routes, and the views.
    
* The app also has a `package.json` file that defines the dependencies and scripts for the app.
    

## How to Connect Jenkins Job and GitHub Repository via GitHub Integration?

To deploy the app using Jenkins, we need to create a Jenkins job that connects to the GitHub repository where the app code is stored. We also need to add a GitHub webhook that triggers the Jenkins job whenever there is a push event on the repository.

To do this, follow these steps:

1. Go to your Jenkins dashboard and click on **New Item**.
    
2. Enter a name for your job (e.g., Node Todo App) and select **Freestyle project**. Then click **OK**.
    
3. On the configuration page, you can add some description for your job if you want.
    
4. Under **Source Code Management**, select **Git** and enter the repository URL: [https://github.com/ajitfawade/node-todo-cicd.git](https://github.com/ajitfawade/node-todo-cicd.git). You can leave the other fields as default.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1692814792943/759c56a0-81f7-4c43-ba43-a94a7f0d68c0.png align="center")
    
5. Under **Build Triggers**, select **GitHub hook trigger for GITScm polling**. This will enable the job to be triggered by GitHub webhooks.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1692814980053/014b9cc5-b7c5-4a90-b333-09943450c6b3.png align="center")
    
6. Click **Save** to save your job.
    

Now, go to your GitHub repository and click on **Settings**. Then click on **Webhooks** and then on **Add webhook**.

Fill in the form as follows:

* Payload URL: Enter your Jenkins URL followed by `/github-webhook/`. For example, [`http://example.com/github-webhook/`](http://example.com/github-webhook/).
    
* Content type: Select `application/json`.
    
* Secret: Leave it blank.
    
* SSL verification: Select `Enable SSL verification` if your Jenkins URL uses HTTPS, otherwise select `Disable SSL verification`.
    
* Which events would you like to trigger this webhook?: Select `Just the push event`.
    
* Active: Check this box.
    

Click on **Add webhook** to create the webhook.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1692815040722/81f1f354-0205-442e-ab68-29ef919478dc.png align="center")

You can test the webhook by clicking on **Edit** and then on **Test**. You should see a green check mark indicating that the webhook was delivered successfully.

## How to Run the App Using Docker Compose?

To run the app using Docker Compose, we need to create two files:

* `Dockerfile`: A file that defines how to build a Docker image for the Node.js app.
    
* `docker-compose.yml`: A file that defines how to run multiple containers for the Node.js app using Docker Compose.
    

Let’s create these files in our GitHub repository.

### Creating the Dockerfile

The Dockerfile for the Node.js app will look something like this:

```dockerfile
# Use node:14-alpine as base image
FROM node:14-alpine

# Set /app as working directory
WORKDIR /app

# Copy package.json and package-lock.json files to /app
COPY package*.json /app/

# Install dependencies
RUN npm install

# Copy app source code to /app
COPY . /app/

# Expose port 8000
EXPOSE 8000

# Run app.js as entrypoint
CMD ["node", "app.js"]
```

This Dockerfile does the following:

* It uses `node:14-alpine` as the base image, which is a lightweight version of Node.js image based on Alpine Linux.
    
* It sets `/app` as the working directory, where the app code will be copied and executed.
    
* It copies the `package.json` and `package-lock.json` files to `/app` and installs the dependencies using `npm install`.
    
* It copies the app source code to `/app`.
    
* It exposes port 8000, which is the port that the app listens on.
    
* It runs `node app.js` as the entrypoint, which starts the app.
    

### Creating the docker-compose.yml File

The docker-compose.yml file for the app and the database will look something like this:

```yaml
version: '3'
services:
  web:
    image: "trainwithshubham/node-app-test-new:latest"
    ports:
      - "8000:8000"
```

This docker-compose.yml file does the following:

The `web` service pulls the image from the Dockerhub in the current directory and maps port 8000 of the container to port 8000 of the host.

## How to Build and Run the App with Jenkins?

Now that we have created the Dockerfile and the docker-compose.yml file, we can use them to build and run the app with Jenkins.

To do this, follow these steps:

1. Go back to your Jenkins dashboard and click on your job name (e.g., Node Todo App). Then click on **Configure**.
    
2. Under **Build**, click on **Add build step** and select **Execute shell** (or **Execute Windows batch command** if you are using Windows). This will allow you to run any shell or batch command as part of your job.
    
3. In the text area that appears, enter the command `docker-compose up -d --build` to build and run the app using Docker Compose. The `-d` flag runs the containers in detached mode and the `--build` flag forces a rebuild of the images if there are any changes.
    
4. Click **Save** to save your job.
    

Now, whenever you push a new commit to the repository, a new build will be initiated automatically.

You will see a new build number appear under **Build History** with a blue ball indicating that the build is in progress. You can click on it to see the details of the build.

Click on **Console Output** to see the logs of the build. You should see something like this:

```bash
[Node Todo App] $ /bin/sh -xe /tmp/jenkins1234567890.sh
+ docker-compose up -d --build
Creating network "nodetodoapp_default" with the default driver
Building web
Step 1/7 : FROM node:14-alpine
 ---> 8a5b9c7f8f6c
Step 2/7 : WORKDIR /app
 ---> Using cache
 ---> 8a5b9c7f8f6c
Step 3/7 : COPY package*.json /app/
 ---> Using cache
 ---> 8a5b9c7f8f6c
Step 4/7 : RUN npm install
 ---> Using cache
 ---> 8a5b9c7f8f6c
Step 5/7 : COPY . /app/
 ---> Using cache
 ---> 8a5b9c7f8f6c
Step 6/7 : EXPOSE 8000
 ---> Using cache
 ---> 8a5b9c7f8f6c
Step 7/7 : CMD ["node", "app.js"]
 ---> Using cache
 ---> 8a5b9c7f8f6c

Successfully built 8a5b9c7f8f6c
Successfully tagged nodetodoapp_web:latest
Creating nodetodoapp_db_1 ... done
Creating nodetodoapp_web_1 ... done
Finished: SUCCESS
```

You can see that the images and the containers are created and started successfully.

You can also verify that the app is running by going to your browser and typing [`http://localhost:8000`](http://localhost:3000). You should see a to-do app where you can add, edit, and delete tasks.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1692815539674/7020543e-b122-474b-b8a1-f4fb954970d8.png align="center")

I hope this blog post helps you understand how to deploy the Node.js todo app with Jenkins and Docker Compose. In the next blog post, I will show you how to use the Jenkins pipeline project to create more complex workflows and stages.

If you have any questions or feedback, please feel free to contact me at:

* GitHub: [https://github.com/ajitfawade](https://github.com/ajitfawade)
    
* LinkedIn: [https://www.linkedin.com/in/ajitfawade/](https://www.linkedin.com/in/ajitfawade/)
    

Thank you for reading! 😊
