# Deploy a Node.js App using Jenkins on AWS EC2 instances

Hello Everyone 👋 In this blog, we are going to deploy a simple Node.js project built on an EC2 instance using Jenkins.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677768568105/4dfd6dde-1fc7-4eea-b83a-5af63cf45e19.png align="center")

What are we going to learn from this Project?

* Set up Jenkins on AWS EC2 instance.
    
* Create a security group for Jenkins.
    
* Connect to Jenkins instance using EC2 security groups
    
* Install Jenkins on the EC2 instance
    
* Creating a Dockerfile
    
* Manage some Jenkins plugins and learn about Webhooks works
    
* Create a job for automating CI/CD deployment
    
* How to integrate Jenkins and GitHub
    

Here's the Workflow for our Project ⬇️

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677768903574/70ecb317-2b10-4b18-9944-c45333f7612f.png align="center")

Github Repo: [Repositor](https://github.com/YashPimple/Jenkins-CI-CD-with-GitHub-Integration)y

Note: Before getting started with the Project you need to have an AWS Tier account and for setting up your AWS account if you are using it for the first time, you can check out this [video](https://youtu.be/FRQ9fE4fd5g)

So let's get started

### Set up Jenkins on AWS EC2 instance

Let start by creating an EC2 instance and running Jenkins on it

* Search for EC2 in the Search bar on the top and click on it
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677924454248/0980395f-65a3-44c6-ac76-36d984187067.png align="center")
    
* Now let's launch an instance by clicking on '**Launch instances**'
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677924582215/670103f4-691e-497b-961e-8f691432b609.png align="center")
    
* Now, enter some details for your instance, name it 'Jenkins-master'
    
* I am opting for Ubuntu Server(free tier) here.
    
* Make sure that the selected server you are opting for, lies in the free tier
    
* Choose the size of the instance "**t2.micro**" or anything that lies in the free tier.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677924482187/c5875f5a-21dd-45e4-a34a-3517177075f8.png align="center")
    
* And now Let's create a key pair for your instance, name it `aws-jenkins` choose "`.pem"`, if you are going to use SSH to connect to your instance, or "`.ppk`" if you are using putty & download it and now launch the instance.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677924504951/ef4d0c1c-57d2-44d7-ac82-c54206afb33f.png align="center")
    
* And Wait for the Status Check to complete (Running)
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677924745284/16b203ca-23e7-4d60-b7a1-6eeca639250d.png align="center")
    

### Now it is time to Connect of instance(Server)

* Click on “Connect” and select the "EC2 instance connect” option.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677925085276/5780bf49-33ea-4412-9680-2ae71feea3e1.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677924908150/30610fee-7b45-44e0-8e08-9def8e225634.png align="center")
    
    * Congratulations, you have now connected to the instance
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677925223150/cabb96eb-df1f-4aaf-988a-78b11cdc55cb.png align="center")
        

### **Install Jenkins on your Instance**

* We are using `sudo` it as a prefix with every command, you can also do `sudo -su` this in the beginning to avoid that.
    
* Enter the command, for a quick update of all the software packages on your instance
    
* Update your system
    
    ```bash
    sudo apt update
    ```
    
* Install java
    
    ```bash
    sudo apt install openjdk-11-jre
    ```
    
* Validate installation
    
    ```bash
    java -version
    ```
    
* It should look something like this
    
    ```bash
    openjdk version "11.0.12" 2021-07-20 OpenJDK Runtime Environment (build 11.0.12+7-post-Debian-2) OpenJDK 64-Bit Server VM (build 11.0.12+7-post-Debian-2, mixed mode, sharing)
    ```
    

* *Install Jenkins*
    
    Just copy these commands and paste them onto your terminal.
    
    ```bash
    curl -fsSL https://pkg.jenkins.io/debian/jenkins.io.key | sudo tee \   /usr/share/keyrings/jenkins-keyring.asc > /dev/null
    ```
    
    ```bash
    echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \   https://pkg.jenkins.io/debian binary/ | sudo tee \   /etc/apt/sources.list.d/jenkins.list > /dev/null
    ```
    
    ```bash
    sudo apt-get update
    ```
    
    ```bash
    sudo apt-get install jenkins
    ```
    
* Start Jenkins
    
    ```bash
    sudo systemctl enable jenkins
    ```
    
    ```bash
    sudo systemctl start jenkins
    ```
    
    ```bash
    sudo systemctl status jenkins
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677999331388/a5a5c17c-9ad5-4615-b7a2-341de51d31d9.png align="center")
    
* Now copy the public IP address of the Jenkins instance, which is present in the details of the instance
    
* Enter this IP address with the port number, i.e., "`<ip_address:port_number>`"- "18.182.13.97:8080"
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677992758766/dba5b4c3-c8d6-4a48-bba1-0038deb01ca4.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677998040061/5f67e6b9-ba12-40a5-9015-e0229f279146.png align="center")
    
    * Now, get the password by entering the following command and enter it in the text box
        
        ```bash
          sudo cat /var/lib/jenkins/secrets/initialAdminPassword
        ```
        
    * Click on install the suggested plugins
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1675595470928/5e440859-4bf1-48b1-8792-682c303d1d42.png?auto=compress,format&format=webp align="left")
        
    * Go ahead and enter your username and stuff as asked
        
    * You are ready to use Jenkins🎉
        

### Creating a Container

* After running Jenkins on our host now is time to create a Dockerfile to create a Dockerfile we need to install it first docker in our instance.
    
    ```bash
    sudo apt install docker.io
    sudo usermod -a -G docker $USER
    ```
    
    ```yaml
    FROM node:12.2.0-alpine
    WORKDIR app
    COPY . .
    RUN npm install
    EXPOSE 8000
    CMD ["node","app.js"]
    ```
    
* Now its time to make docker image and container out of the docker file
    
    ```bash
    sudo docker build . -t node-app
    
    sudo docker run -d -p 8000:8000 todo-node-app
    ```
    
* To see our Project running we need to add port in our security group of the instance
    
* Follow the same steps, as followed in adding an inbound port for Jenkins, with some minor changes.
    
* One inbound rule need to be added
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677992675242/ef162864-c2b1-4f0e-9290-3f4270561ce3.png align="center")
    
* Now copy the public IP address of the Jenkins master instance, which is present in the details of the instance
    
* Enter this IP address with the port number, i.e., "`<ip_address:port_number>`" - "18.182.13.97:8000"
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677993087587/02fb0bbd-b1a9-41c2-8787-e8a5e87b45a1.png align="center")
    
* Here you have finally deployed your node project using AWS now ⬇️
    

### Automating CI/CD using Jenkins

* First, you need to create a New Jenkins freestyle Pipeline
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677993753071/c7529635-b9ed-49bb-8e0e-cbbf07035665.png align="center")
    
* After creating a Job we need to create a private and public key which will be used to integrate our GitHub and Jenkins for the Continuous Integration part.
    
* Going back to our instance to create public and private key we need to follow up the following commands.
    

```bash
ssh-keygen
cd .ssh
ls
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677994198874/a644165e-9ca5-4aa0-b710-d708cd9f551b.png align="center")

```bash
sudo cat id_rsa.pub
```

Where `id_rsa.pub` stands for Public Key and `id_rsa stands` for Private Key

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677994219988/3ad3c148-ac8e-4b69-afec-d9916284248a.png align="center")

```bash
sudo cat id_rsa
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677994231473/57ce727a-229e-43e9-b961-8a877b19e4f1.png align="left")

* After generating the Public and Private Key now we need to connect our Jenkins with Github for that we need to create an SSH KEY.
    
* Go the Github Settings &gt; click on SSH and GPG keys &gt; Give any title and paste the Public Key we generated &gt; click on Add SSH Key
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677994427927/4381074b-6dc3-444a-880f-82c133e10b4c.png align="center")
    
* Now let's go back to Jenkins after creating the freestyle Project now we need to add the respective credentials
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677994632130/8e012021-0c17-4573-a3cb-6f1e2a03c3e9.png align="center")
    
* Give the Jenkins Project a Description after that add the Repo url "[Github Link](https://github.com/YashPimple/Jenkins-CI-CD-with-GitHub-Integration)"
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677994816101/f164249a-f1e8-4688-994a-f844b88f8ca8.png align="center")
    
* In the Source Code Management, choose git and enter the repository URL, by clicking on code.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677994834248/25ed1453-7028-40a2-a555-3b6c4f2e0191.png align="center")
    
* Create a new credential by clicking on add and new pop-up screen will appear overhere Select kind to be "`SSH Username with private key`", let the scope be global.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677995454120/a92b47a2-6688-418d-b0e6-1230971164e1.png align="center")
    
* Further, add the Private Key generate in the instance and paste it over here and click on add button to save it.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677995545466/31bfeeca-6e96-49c8-b3f0-5e01d0ff07e2.png align="center")
    
* After select the ubuntu credentials and Since all the code is in the master branch in the given project, we will use the master branch.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677995773582/4df38544-1ef9-4252-90ac-ec9662a1c2ae.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677995827889/2cbd5240-e5ec-4af2-b2ac-f4490aa3b5c2.png align="center")
    
* Here click on the "Github hook trigger for GITScm polling" tick is so the any chance made in the Github code base can be reflect over here and a new build can be executed for that we need to make a small change in our Project Repository and all this work is done by Github Webhook &gt; Go to Project Repo Settings &gt; Webhook &gt; Add webhook
    
* Over their you need to enter your this IP address with the port number, i.e., "`<ip_address:port_number/github-webhook/>`"- "[`http://54.250.242.79:8080/`](http://54.250.242.79:8080/)`github-webhook/`" and select content type as "`application/json`" and click on "`Add webhook`"
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677996473985/b5710295-55ea-4dd0-9f79-bd8235f8a041.png align="center")
    
* Then let's go back to Jenkins Pipeline to work on the continuous deployment part for creating our docker image.
    
* Now Let build steps to create our Docker container
    
* Select Execute Shell and all the following CMD
    
    ```yaml
    docker build . -t node-app-todo
    docker run -d -p 8000:8000 node-app-todo
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677996592218/82df4420-ceca-4851-9782-6568dba74f32.png align="center")
    
* Now save and click on “Build Now”
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677996927465/611190ac-32cc-4e70-a06b-36a218bccd0b.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677996937522/9f94094c-f99e-478f-a4d0-ef8deb1327bd.png align="center")
    
* Yay! 🚀 that's a SUCCESS!
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677997050905/fd18967e-b5cf-4922-8f52-fa1e8964a7e1.png align="center")
    

That's all for now. If you have any questions, please leave them in the comments section and I will do my best to answer them. Thanks for reading. Any feedbacks are welcome!! :). Connect with me on [**Twitter**](https://twitter.com/Yashpimple22). Follow me for more such blogs on [**Hashnode**](https://yashpimple.hashnode.dev/).

Follow DevOps Community on [**Hashnode**](https://devopscommunity.hashnode.dev/) and [**Github**](https://github.com/rohitg00/DevOpsCommunity)
