CI/CD and Deployment Of NodeJs to Heroku Using Jenkins on Google Compute Engine

In this article, we will create a CI/CD pipeline that will deploy our nodejs app to Heroku using Jenkins on google compute engine.

What is CI/CD?

Continuous Integration(CI) and Continuous Delivery(CD) involve developers making changes to code frequently and these changes are tested before being deployed to the production environment. The tests and deployment are done automatically using CI/CD pipelines. This way changes made are deployed faster, safer, and reliably.

What is Jenkins?

Jenkins is an open-source automation server that enables developers to reliably build, test and deploy their software. Currently, it offers more than 1,000 plugins, so it integrates with almost all DevOps tools, from Docker to Puppet. With Jenkins, you can set up and customize your CI/CD pipeline according to your own needs.

In this article, you'll need:

  • A Google Compute Engine Vm
  • An Heroku account
  • A GitHub account
  • Jenkins

Google Compute Engine

Google compute engine is an Infrastructure as a Service (IaaS) that allows users to execute workloads on google physical hardware.

Google offers new customers $300 in free credits to spend on Google Cloud for 90 days. All customers get a general-purpose machine (f1-micro instance) per month for free, not charged against your credits. How to open a GCP free tier account

Launch a compute engine VM

Once you've created the gcp account, click on the sidebar, go to compute engine and click VM Instances. Click the plus + sign to create the vm instance and configure your vm as shown below:

jenkins-server.PNG

blog post.PNG

The default boot disk is "Debian GNU/Linux 10 (buster)", click change, under operating system select Ubuntu and under version select, Ubuntu 18.04 LTS, leave the remaining options as default and click select. Under firewall select allow http traffic, leave all other settings as default and click create. Wait for the instance to start up and you'll be given an internal and external-ip address and can connect using ssh.

Running the app locally

Fork this repository to your repository https://github.com/ToluwalopeAyo/Jenkins-Weatherapp.git

Clone it to your local system git clone https://github.com/<username>/Jenkins-Weatherapp.git

Change into the directory, install dependencies and start the app

npm install
npm start

Go to your browser and enter localhost:3000

jenkins-server.PNG

Installing and Setting Up Jenkins

In GCP, go to your VM instances page, you'll see your instance up and running. Click on ssh and connect to your instance Before we can use Jenkins, we need some dependencies and we need to install Jenkins to the server.

sudo apt install openjdk-11-jdk openjdk-11-jre -y

Add the jenkins repository key to the server

wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -

Add the debian package repository to the servers sources lists

sudo nano /etc/apt/sources.list
deb https://pkg.jenkins.io/debian-stable binary/

Update your local package index, then finally install Jenkins

sudo apt update
sudo apt install jenkins -y

Set Jenkins to start

sudo systemctl start jenkins

Check Jenkins status

sudo systemctl status jenkins

blog.PNG

Set the Jenkins service to be available at boot

sudo systemctl enable jenkins

Let us now configure Jenkins

Open your browser and go to external-ip:8080, Jenkins listens on port 8080. You will see the Unlock Jenkins page and the location of the admin password. Copy the password and use it to login.

Jenkins setup.PNG

Then click on install suggested plugins After installation, we'll create our first admin user. Fill in your username, password, full name and email address and click Save and Continue. Skip the Jenkins URL configuration and we can start using Jenkins.

Adding GitHub plugins to Jenkins

Go to manage Jenkins and click manage plugins Search for Github and Check under installed, you'll see that the github plugin is installed already

gitjenks.PNG

Creating a Pipeline

On the Jenkins Dashboard, Click on New Item Give it a name of your choice, and click on Freestyle project then click OK.

blog post.PNG

In the General section, tick the Github Project box and enter the link to your github repository.

Under Source Code Management, click on Git and enter the same link to the github repo.

Under Branches To Build, enter main, our code is in the main branch of the repository.

Let us confirm that the pipeline can build successfully from the github repository.

Make sure your configuration is just like the one below and Click Save.

Jenkins setup.PNG

Useful.PNG

Click on Build now and the build should be successful. Click on the build number and Go to the console output, you would see something like this

jenk.PNG

Building to Heroku

  • Create a Heroku account if you don't already have one
  • Click on create new app, give it a name of your choice and choose your preferred region.

heroku.PNG

Go to your account settings, scroll down, copy your API key and keep it somewhere, you would be needing it later.

api key.PNG

The app we just created, go to the app settings and copy the heroku git URL git.heroku.com/.git

In Jenkins, click manage jenkins > Manage credentials > Jenkins > Global credentials (unrestricted)

On the side menu click add credentials

Enter your heroku username or email address and the API key you copied and click ok.

Hi.PNG

On the dashboard, click on the pipeline that we created earlier and click configure

Under Source Code Management, click Add Repository and enter the Heroku git URL we copied earlier

You would get an error, looking like this

Screenshot.PNG

Under credentials, you would see the one you created earlier, select it and the error should clear out.

Click Advanced and give the repo a name, we would be needing it later.

Click Save. This is because we have to save the repo name first.

Click on Configure again

Under Build Triggers, select GitHub hook trigger for GITScm polling

Under the Build section, Click on Add build step button and then click on Execute shell. Enter the following code into the shell

git checkout -b main

Under the Post Build Actions, select Git Publisher

Select ```Push Only If Build Succeeds````

Select Force Push

Click on Add Branch

In the Branches to Push box, enter main this is because heroku, uses the main branch

In the Target remote name, enter the name we gave to our heroku repo earlier

So far your configuration should look like this and click on save

11.PNG

12.PNG

13.PNG

14.PNG

15.PNG

Click on Build Now and the build should be successful. When you check the console output, you would see something like this.

16.PNG

Go to heroku and check the overview of the app, you would see that the build succeeded.

image.png

Click on Open app and you would see the Weather App.

Automating Our Pipeline

When changes are pushed to the github repository, you'll have to manually go back to deploy the changes on Jenkins which can be sometimes stressful. We're going to set up Jenkins and Github in a way that once changes are pushed to the repository, Jenkins would automatically deploy to Heroku. We would be using Github Webhooks.

Add Github webhook to push events to Jenkins

Webhooks allow you to build or set up integrations, which subscribe to certain events on GitHub.com. When one of those events is triggered, it sends a HTTP POST payload to the webhook's configured URL. Webhooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server.

Go to your github repository settings and click Webhooks

18.PNG

Click on add webhooks

Enter the external-ip address of your jenkins VM like this http://<external-ip>:8080/github-webhook/

image.png

Go back to jenkins and configure the pipeline, clear out the git checkout -b main in the execution shell and save it.

You can now push changes to the repository and Jenkins will automatically deploy to heroku.

I wrote this article because I came across several issues when configuring my pipeline and most articles I saw were either outdated or too cumbersome. I really hope this saves you the stress I went through and you find this very useful. Thanks for reading.