How to Dockerize an Existing Node.js Application and Build a Jenkins Pipeline Using AWS EC2 Instance

How to Dockerize an Existing Node.js Application and Build a Jenkins Pipeline Using AWS EC2 Instance

Hi there,

What we will be practicing today is how to dockerize an already existing Node.js application and how to handle the multibranch automation process using Jenkins. Note that we will be making use of the AWS EC2 instance.

Explanation of Terms

Before we continue, there’s a need to define some terms that we will be using to have the basic knowledge of what we’re doing.

Docker

Dockerfile

Node

Jenkins

Docker: This is a platform that is used to build, test and deploy applications in a container without depending on the OS of the host (which is the OS of your PC).

Dockerfile: These are set of instructions written in a file to build an application.

Node: This is a javascript runtime that enables the running of javascript on the server

Jenkins: This is an automation server that is used to build, deploy and automate any project using different plugins.

Explanation of Project

The first thing we need to do is to look for an already existing Node.js project on Git (you can go ahead to build one if you can). For this article, I will be making use of a repository by Kriscfoster.

Step One: The first thing you need to do is to create an aws account, create an instance on AWS and SSH into the instance.

To create an account on aws

To create an instance with aws

To ssh into the instance

Step Two: Fork the repository and clone it to your AWS EC2 instance. Note that you must have Git installed on your AWS EC2 instance before you can make use of the Git command. After cloning the project, type “ls” on the terminal to see the available files and folders and you will see the project you just cloned there too.

https://github.com/ninyhorlah/end-to-end-testing-todo-app.git

Step Three: Change your working directory to the project you just cloned and run npm install

cd end-to-end-testing-todo-app/

Step Four: The next step is to create a Dockerfile that will take in the instruction to dockerize your node application. On your terminal, type touch Dockerfile and click enter

touch Dockerfile

Step Five: Open your Dockerfile using vi Dockerfile and hit enter.

vi Dockerfile

Step Six: To make the file editable, press Esc followed by i and we can then type in our instructions. Type the instructions below into your Dockerfile and once you’re done, press Esc followed by :wq! to save and close the file.

FROM node

WORKDIR usr/src/app

COPY package.json .

RUN npm install

COPY . .

EXPOSE 5000

CMD "node" "server.js"

Explanation of the Command Inside the Dockerfile

Line 1: This simply means were pulling a node image.

Line 2: This shows that we set a working directory for our application.

Line 3: This means that we’re copying package.json into the working directory.

Line 4: We're running npm install once we’ve copied the package.json

Line 5: This means that we copied everything inside our folder.

Line 6: We expose the port in which the application will run when we search it on the browser.

Line 7: This simply shows the command that is required to run the application.

Step Seven: The next thing to do is to build the Dockerfile and tag it to a name that we can use to access it later. Before we can do that, make sure you have Docker installed on your server.

To install it, follow this tutorial provided in the AWS amazon doc

Once you have docker installed, you can build your docker image using:

sudo docker build -t todo-docker

Step Eight: Once the build is successful, you can then push your code on GitHub. For best practice, it is good to switch to your working branch before doing anything at all. So because we forgot to do it earlier, we will push this code on GitHub and then create a dev branch that we will continue our work on

git checkout -b branch

Step Nine: The next thing to do is to run our dockerized application but before it can run on the browser, we need to create a security group for the port. To do that,

  • Select your server or instance name

g1.png

  • Under security, click on the security group link

g2.png

  • Click on edit inbound rules

g3.png

  • Click on save rules g4.png

Add the port number and save rules. After that, you can access it on your browser

g5.png

To access your app on the browser, you can use either the public IPv4 address provided in your instance mapped with your port number or the address you used to SSH into your instance (the one after the @) mapped with your port number

g6.png

or

g7.png

This is what your app will look like on the browser if you do follow all the steps

g8.png

Congratulations!!! You have just finished the first phase of the project and it’s now running on your browser. The next step now is to handle the automation process with Jenkins.

Are you ready? Let’s Go.

Automating Our Application Using Jenkins

If you’re still here, I’m super proud of you for making it this far with the zeal to learn more. Before you can get your Jenkins running, you must have Java installed on whatever you want to run it on. For this article, we’ve been making use of the AWS EC2 instance and that is what we will continue with.

To know if you have java installed already, kindly check the version to be sure by doing the java -version If Java is installed, you will see the version as shown in the image below:

java -version

g9.png

This simply shows that version 11 is installed but if you get a message saying java command not found, it means you’ve not installed java and that is the first thing you need to do.

g10.png

To install java, Kindly follow this article by Rahul to get your Java installed. Once you’re done with that, you can continue with the steps to get Jenkins running.

We will be making use of the official image of Jenkins on the Docker hub and running it in a container.

g11.png

This is what you will see when you click on the Jenkins Official image with instructions on how to run it. Make sure you read the documentation well

Note: the container name to use is jenkins/jenkins as just jenkins will not work.

g12.png

Step One: On your terminal, write the following as seen in below:

docker run -p 8080:8080 -p 50000:5000 -d -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts

This is what you will see when you’re able to pull Jenkins successfully:

g13.png

To see if your Jenkins is running, type docker ps in your terminal as seen below:

docker ps

g15.png

You can see that you have two images running, Jenkins and your todo application.

Step Two: Now that Jenkins is running, the next step is to open it on your browser and then set it up. Before you can access it on the browser, we need to add a security group for port 8080 just like we did earlier for port 5000 of our todo app. If you don’t know how to do it, please scroll up to see how it was done.

To view it on your browser, use the public IPv4 address of your AWS instance or the address you used to SSH into your instance. Scroll up for example.

If you’re able to pull Jenkins successfully, the result on your browser should look like the image below:

g16.png

Step Three: The next step is to get the secret key that will enable you to set up your Jenkins account. To get the key, simply type docker logs container_id

docker logs f8c9cc29ef1d

then scroll to where the key is written. See the image below for reference:

g17.png

Copy the key and paste it to where Administrator Password is required then click continue. If you’re able to get it right, the result will be the same as what we have in the image below:

g18.png

Step Four: Click on Initial suggested plugins so that necessary plugins will be installed and this is what you will see:

g19.png

Once the installation is done, a getting started page will come up that will require you to set a username, password, full name and email address as seen in the image below:

g20.png

Step Five: Create your profile and move it to your dashboard:

g21.png

g22.png

g23.png

Step Six: Click on New Item, input the item name, select multibranch pipeline and click on OK.

g24.png

Note: After you click on OK, you might get an error as shown in the image below:

g25.png

To resolve it, head over to your dashboard, click on Manage Jenkins:

g27.png

Scroll down a little bit, click on Configure Global Security under the security section:

g28.png

Scroll down a little bit, you will see CSRF protection. Afterwards, check the enable proxy compatibility box and click on save. Note: do not click on apply.

g29.png

Once you’re done with that, go back to step three above to create a multibranch pipeline.

Step Seven: The next step now is for us to create credentials for our pipeline. We will create two different credentials. One for the pipeline parent (every other job can access it) and the other is scoped to the pipeline job we’re working on.

To Create Credentials for the Pipeline Parent

  • From your dashboard, click on the job name you created

a1.png

  • Click on credentials. Now you will notice names such as stores from parent and stores scoped to sca-pipeline (this is the name of the item you created), the one we’re working with first is the stores from the parent.

a2.png

  • Click on Jenkins under stores from parent.

a3.png

  • Click on Global credentials(unrestricted).

a4.png

  • Click on add credentials.

a5.png

  • After you have clicked on add credentials, you will have the same result as seen in the image below:

d1.png

We will create two types of credentials here, one for global and the other for the system:

  1. Global credential

  2. Leave the scope the way it is, type in a username, password and ID you want to use and click OK.

d2.png

  1. System Credentials

  2. Click on add credentials again, this time, change the scope to the system by selecting it in the dropdown, type username, password and ID, then click OK.

d3.png

d5.png

If you’re able to do it correctly, this is what your result will be:

d6.png

To Create Credentials for the Job Pipeline

The credential we are creating here should be that of the GitHub repo you want to use:

  • From your dashboard, click on the job name you created, click on credentials and click on the job name under stores scoped to sca-pipeline (this is the job name you created).

f1.png

  • Click on global credentials and click on add credentials just as we did before.

f2.png

  • Fill in the credentials of the GitHub repo you’re making use of here and click OK.

f3.png

Step Eight: Go back to your job dashboard and click on configure.

f4.png

Step Nine: Under the branch source, select Git.

f5.png

Step Ten: Fill in the credentials as seen in the image below and click save.

f6.png

If done well, you will get a log report showing your branches and stating that the Jenkinsfile was not found. The next thing now is to create a Jenkinsfile

Creating a Jenkinsfile

Step One: Head over to GitHub and create a Jenkinsfile in one of the branches of the repository you’re using.

k1.png k2.png

Step Two: Type the following inside the file you created.

pipeline{

   agent any

   stages{

       stage("build"){
          steps{
              echo "building the application..."
         }
      }

     stage("test"){
          steps{
              echo "testing the application..."
         }
      }

     stage("deploy"){
          steps{
              echo "deploying the application..."
         }
      }

   }
}

Step Three: Write a commit message and commit your changes by clicking commit new file.

k3.png

Step Four: Go back to your Jenkins dashboard, click on scan multibranch pipeline now and afterwards click on scan multibranch pipeline log.

If you check through the log, you will see that Jenkinsfile is now found in the dev branch.

k4.png

Click on the status and you will see if your build is successful or failed.

k5.png

Step Five: The next step is to automatically scan the multibranch pipeline without the need to do it manually. To do that, click on configure and scroll to scan multibranch pipeline triggers. Check the box and set the interval to 2 minutes (note that you can set it to your preferred time). After that, click on save.

k6.png

Now, you don’t need to scan your pipeline manually as it will be done automatically now. Congratulations! You have successfully dockerized a Node.js app and also automated the Jenkins process. Thank you for following through. Don’t forget to like, clap and follow for more articles. See you later.