# Project : Effortless Web App Deployment with Jenkins Master and Worker Nodes

Today we will deploy node.js app on EC2 Server using Jenkins master and Worker nodes.

We will be using this project : [https://github.com/patelajay745/node-todo-cicd](https://github.com/patelajay745/node-todo-cicd)

## Pre-requisites

You should have two EC2 instances with a fresh Ubuntu 22.04 Linux installation. To get an agent working make sure you install Java ( same version as jenkins master server ) and Docker on it.

Let's start.

This is my instance for master node(jenkins\_server)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685067130973/d890ae58-f5da-4468-aee8-51fb90707e5f.png align="center")

This is my instance for agent node(jenkins\_agent)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685067172203/ae1ba193-a1dc-4afe-8ff9-a1921e520c07.png align="center")

<mark>Now we need to do ssh-keygen for secure communication between two instances.</mark>

Go to your jenkins\_server type "ssh-keygen" it will ask path and passphrase. we can keep it black to save it as default.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685067224545/b31eade8-f901-46c1-b6fb-ff264ab56cba.png align="center")

now go to .ssh folder and you can see two files: id\_rsa(private key) and id\_rsa.pub(public key)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685067449566/aadbc116-4e5a-4681-98bf-a66dbeb4148b.png align="center")

now copy your public key . you can use "cat" to see and copy it.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685067523353/c7b37559-022b-45de-96c3-a1899c87b27f.png align="center")

now go to your jenkins\_agent instance and go to .ssh folder.

edit your authorized\_keys using "vim" and paste your copied public key from jenkins\_server.and save it.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685067580051/7709b3eb-5b32-4c98-b7e2-3df91684c3f9.png align="center")

Now everything is set up. Now we will use our Jenkins to create our pipeline. Before that we need to do some setting in our Jenkins so Go to your Manage Jenkins.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685067686705/cc0fb7ee-ad80-40ff-a0f3-c4952c2c2b74.png align="center")

click on Manage Nodes and Clouds.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685067795964/b60e7328-0ce2-4c2b-8920-581b00549a6e.png align="center")

Create a New node. Give a name to it and select permanent Agent.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685067830739/c5816b1b-5493-4be8-a89a-fed4a3c85994.png align="center")

Give a description if you want. You should set "Remote root Directory", where all code from GitHub will be saved. I will use "/home/ubuntu/agent1"

You should give a label to this agent(it is very important as we will run our pipeline by this label only)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685067938410/9a0bc06f-6bca-4a5e-a4d6-0c875da66672.png align="center")

In the Usage you should select "Only build jobs with label expressions matching this node"

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685068207383/c1c8dcce-0e7a-4fbe-9ee7-5a842a2add08.png align="center")

now go to Launch method below and select "<mark>Launch agent via SSH</mark>"

<mark>Enter your public IP of your jenkins_agent in Host</mark>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685068364285/53179eb2-9415-488f-9301-1a089d85e115.png align="center")

In credentials, you should click on Add. which will open a new window like below.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685068506107/56355565-e375-4943-a0b5-1f82c782afc8.png align="center")

select SSH username with private key. give id to it.

username should be "ubuntu" and in the private key section add your jenkins\_server private key. and save it.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685068643080/f433fc19-31ea-42f9-9689-5c189ea87a50.png align="center")

in the "**Host Key Verification Strategy,"** you should select "<mark>Non verifying verification strategy</mark>" and create your node. your Node will look like below screenshot.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685068769893/96138cda-bc87-428d-bec2-ea8c1b442a9e.png align="center")

if you check the console of agent then it will show agent successfully connected and online.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685068803413/ddeaa740-fd80-4ab0-9c63-18df281d9195.png align="center")

Now It's time to create Our declarative pipeline . click on "New Item" and select pipeline. click ok.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685068860789/d01c24d6-e994-42bc-a22a-01359414fdaa.png align="center")

you can give description to it and url of GitHub project. we are using [https://github.com/patelajay745/node-todo-cicd](https://github.com/patelajay745/node-todo-cicd)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685068948452/de022cb9-1523-43a2-9f02-37dfb8a3971e.png align="center")

we need to enter our Groovy pipeline script.

```bash
pipeline {
    agent { label "agent1" } 

    stages {
        stage('Checkout') {
            steps {
                git url : "https://github.com/patelajay745/node-todo-cicd/", branch : "master"
            }
        }
        stage('Build and Test') {
            steps {
                sh "docker build . -t node-app-new:latest"
            }
        }
        stage('Push To DockerHub') {
            steps {
                withCredentials([
                    usernamePassword(
                        credentialsId: "DockerHub",
                        passwordVariable: 'PASSWORD',
                        usernameVariable: 'USER'
                    )
                ]){ 
                    sh "docker tag node-app-new:latest ${env.USER}/node-app-new:latest"
                    sh "docker login -u ${env.USER} -p ${env.PASSWORD}"
                    sh "docker push ${env.USER}/node-app-new:latest"
                }
                
            }
        }
        stage('Deploy') {
            steps {
                sh "docker-compose down && docker-compose up -d"
            }
        }
    }
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685069009535/b2d62276-54a8-4012-a5de-f532a31bf26c.png align="center")

Let me explain it.  
  
`agent`: Specifies the agent or node where the pipeline will be executed. In this case, the label "agent1" is used to identify the specific node.

1. `stages`: Defines a sequence of stages in the pipeline. Each stage represents a specific phase of the build and deployment process.
    
2. `stage('Checkout')`: The first stage is named "Checkout" and is responsible for cloning the source code repository from GitHub using the `git` step.
    
3. `stage('Build and Test')`: This stage builds the Docker image for the Node.js application using the `docker build` command. It tags the image as "node-app-new:latest".
    
4. `stage('Push To DockerHub')`: This stage handles pushing the Docker image to DockerHub. It uses the `withCredentials` block to securely provide DockerHub credentials (username and password) stored in Jenkins credentials store. It tags the image with the username and pushes it to DockerHub.
    
5. `stage('Deploy')`: The final stage is responsible for deploying the application using Docker Compose. It first shuts down any existing containers using `docker-compose down` and then starts new containers in detached mode using `docker-compose up -d`.
    

we have used environmental variable using "[**Environment Injector Plugin**](https://plugins.jenkins.io/envinject)**"**

Now save it and click on build now . if everything is okay then your stage will look like below.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685069474636/7bd4a9c6-2650-430c-bda5-4fc32539926f.png align="center")

and if everything is build successfully then you can check your jenkins\_agent public Ip:port on which your application is running.

That's it.It was all for Day 28 of #90daysofdevOps.You have created your CI/CD pipeline using Jenkins master and agent node.

I hope this blog helps you to create and clear your doubt about it, if now then please comment below , I will happy to help you out. See you with another challenge.

#Jenkins #Docker #CI/CD #DevOps #WebAppDeployment #Nodejs #Automation #SoftwareDevelopment #ContinuousIntegration #ContinuousDeployment #PipelineAsCode #DevOpsTools #SoftwareDelivery #TechBlog
