Continuous Integration and deployment (CI/CD Pipeline) with Jenkins and Node.js

Jenkins and Node

Write code, test and deploy

This is one of the common development cycles of any developer.

Most of the time testing and deployment steps do not change frequently and in order to keep the developer focus on writing code, we do the automation of testing and deployment.

This automation is called “continuous integration and deployment” OR CI/CD Pipeline.

In this tutorial, we will learn how to set up continuous integration and deployment (CI/CD) infrastructure for the Node.js project.


I am going to use Jenkins as the automation tool and Github as source code management system.

Jenkins is free for use but we require public server in order to integrate the Github repository.

For the server, I will be using $5 droplet on Digitalocean. In case you wish to buy it, you can use this link to get the $10 off for the first month.

How it’s going to work

Here is the complete flow of the system.

  • You made some changes in your project.
  • You push those changes in Github on master or any branch.
  • Github will notify Jenkins about the new push. ( We will configure it )
  • Jenkins will then run the commands you ask it to run.

Those commands will contain the following.

  • Test script.
  • Deployment script.

Deployment script will be added to Project only and Jenkins will use that to communicate to Server and perform the push.

Basically, what you do manually such as running test command, login in to Server, performing Git pull, and then restarting the build server, we will do all of them automatically by writing the script.

Continuous Integration and deployment with Jenkins and Node.js

Creating a project

You need a Node.js project hosted on Github to perform the testing and deployment. I am sure most of you already have projects at Github written in Node.

For those who do not have one, let’s create one together.

Go to to create new repository. Give it proper name and initiate it with README file and choose Node as .gitignore file.

Devops nodejs

After creating a new repository, clone the project on your local system using the following command.

git clone

git clone

Let’s create a simple Express project to deliver the “Hello World” message. Switch to the clone folder and run npm init -y command to generate the package.JSON file.

  "name": "sampleCode",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  "keywords": [],
  "author": "",
  "license": "ISC"

Install express using the following command.

npm i --save express

Create new file named “app.js” and put the following code in it.

var express = require('express');
var app = express();

app.get('/',function(req,res) {
  res.send("Hello World");


Run the code using pm2 start app.js command and visit http://localhost:4000 from your browser to view the app.

PM2 is process manager and we recommend you to use it. Here is the article on same.

So we have a basic app ready to go. Let’s write one simple test case which perform the home page accesibility checking.

First, install supertest, mocha and should packages.

npm i --save-dev supertest should mocha

We need mocha globally installed too. Run this command to do so.

sudo npm i -g mocha

Create new folder named “test” and new file inside it named “test.js”.

mkdir test && cd test

Paste the following code in it.

var supertest = require("supertest");
var should = require("should");

// This agent refers to PORT where the program is running.

var server = supertest.agent("http://localhost:4000");

// UNIT test begin

describe("SAMPLE unit test",function(){

  // #1 should return home page
  it("should return home page",function(done){
    // calling home page
    .expect(200) // THis is HTTP response
      // HTTP status should be 200


Run your node app then run the following command from another tab.


You should be able to see the console like this.

Mocha Devops

Ok, so we have our app running with the test. Let’s push it to Github.

First add all files.

git add .

Add new commit.

git commit -m "first push"

Push it.

git push

Adding Github webhook to push events to Jenkins

When any changes i.e commits are pushed to the Github repository, we need a mechanism to notify that event to our Jenkins Server which we going to configure in next section.

Github allows us to add Webhook services to achieve same. Open GitHub repository, go to settings and click “Webhooks and Services” from side panel. Click on “Add Services” and search Jenkins, click on “Jenkins Github Plugin”.

Note: Don’t choose Git one.

Adding Github webhook

After that, add the webhook URL which is in the following format.

webhook screen

Click on Add Service and you are good.

Creating droplet and Installing Jenkins

I am using DigitalOcean as Web Hosting. You can use any Server as you like, in case you want to host your app on DigitalOcean and looking forward to buying it, you can use this link to get $10 discount on our side.

Click here to go to DigitalOcean droplet creation screen.

Continous integration for Node

Choose $5 plan and create the droplet.

After creating a droplet wait for some time, DigitalOcean will send you an email containing the credentials.

Login to your droplet using the following command.

ssh username@dropletip

Provide the password given in the email and you are good to go. Once you are log in, update the kernel using the following command.

sudo apt-get update

We need the Java runtime system to execute Jenkins. Run the following commands to install it.

sudo apt-get install default-jre
sudo apt-get install default-jdk

Run following commands one by one to install Jenkins.

sudo wget -q -O - | sudo apt-key add -
sudo sh -c 'echo deb binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

After installation, Jenkins will automatically start itself and you can visit the domain-name:8080 to access it.

Continous integration for Node

We have installed Jenkins, let’s add the Github plugin in Jenkins in order to integrate the project.

Adding Github plugin in Jenkins

Click on “Manage Jenkins” and then click on “Manage Plugins”.

Plugin Jenkins

Now search for “GitHub” from search bar placed at right side of the screen and choose the Github plugin. There are many more with similar names but choose the one shown below.

Github plugin

Click on “Install without restart” and in a few seconds plugin will be installed.

plugin installed

Configuring project with Jenkins

We have our project ready and hosted at Github and Jenkins installed, all we need now is to integrate both of them so that when we push any changes to Github, Jenkins knows about it and does the testing and deployment.

Click on “New Item” and fill in the proper project name. Choose “Freestyle project” among the options.

Continious integration using Node.js

In configuration screen, check Github project and add the Github project link. Under “Source Code Management” select Git and add the Repository URL with .git extension.

You can choose which branches you want to cover up in the deployment process or leave it blank for any branch.

Under “Build Trigger” section select “Build when a change is pushed to GitHub” option. This is very important.

Under “Build” section, Click on “Add build step” button and then click “Execute shell” option.

In that for instance type “npm install” and then click on Save. Here is full-page screenshot.

Jenkins configuration

Let’s check if we have Github and Jenkins talking to each other.

Make any changes in the project and do the commit and push. As soon as you push new changes Jenkins will show you new build in the project dashboard.

Building process Jenkins

You can replace the command with mocha in order to do testing first.

Configuring deployment process

We have Github communicating to Jenkins, it’s time to perform the deployment to our Server. One thing, Jenkins will not directly communicate to your web server. All it can do is to run instruction which you want it to run.

So let’s first list down the steps we manually perform to do the deployment to any Server.

  • Login to Server using SSH.
  • Switching to project directory.
  • Pulling code from Github.
  • Restarting process manager ( say pm2 ).

We will write down all of these commands in one file and tell Jenkins to execute them.

But, what about the SSH username and password? Of course, Jenkins won’t enter it as we do. We need to make sure Jenkins can perform SSH login without using the password to our Server.

To achieve that, we will generate the SSH key manually from Jenkins Server and add it to our Development Server.

Let’s do it.

Login to Jenkins Server using Terminal and switch to root user using this command.

sudo su

Jenkins automatically creates a new user after installation. Switch to it using this command.

su jenkins

Let’s generate an RSA key, run the following command.

ssh-keygen -t rsa

Press Enter for the location and do not type any password when it asks to, just hit enter.

Once the process is completed, print the public key information using this command.

cat ~/.ssh/

It should start with ssh-rsa and ends with jenkins@droplet-ip. Copy the key.

Now login to your development server and switch to ~/.ssh directory using following command.

cd ~/.ssh

If it’s not present, create one using this command.

mkdir ~/.ssh

Now open the file named authorized_keys if its present, else create one.

nano authorized_keys

Paste the key in the file, if there is already some information is present, just append the key in the new line and do not change anything else.

Once done save the file.

In order to validate whether keys are properly configured or not, switch to Jenkins Server and try to login to the development server using SSH.

ssh userName@development-ip

If it’s not asking for any password and log in successfully, you are good to go.

Now we have both the Server connecting each other. Let’s write the deployment script and finish this job.

Create a new file in your project directory with no extension. I name it deploy.

Paste the following code in it.

ssh userName@development-server-ip <  cd /your-project-path 
 git pull      
 npm install --production      
 pm2 restart all

Save the file. Each line of the code in this file is what you actually do manually, I don’t think so I need to explain this.

Make the file executable using the following command. This is important for the Shell script to execute.

chmod +x deploy

Go to Jenkins project page, from left navigation click on “Configure” and scroll down to “Build” section.

Add “./deploy” in the build commands. Here is screenshot for same.

Adding deployment script

Click on Save.

Now in the project directory, add the deploy file, commit and push it to Github.

Check the second build in Jenkins.

Build process

Refresh your project page and you shall see the changes updated in the project.

It Works. We have automated the process to do the testing and deployment every time we make some changes in the project.

Tips for integrating Github private repository or organization with Jenkins

Setting up Jenkins for the private repository is similar to what we did above. I personally configured the continuous integration and deployment environment for my organization using the same steps I mentioned above except some little extra efforts due to Server configuration ( This is my guess ).

When Jenkins was trying to pull the code, it was throwing an error due to the HTTPS method used by Github. I stumbled upon various methods and nothing worked for me. I changed the HTTPS origin to SSH origin and updated the repository origin too in the Development server.

I also configured my account to use the SSH key in order to perform the Git operation without authentication and that you may need in order to let Jenkins do the code update.

Here is what I did.

Go to this official doc of Github to generate and add the SSH key in Github. You need to generate an SSH key in your development Server and add the Public key in Github.

Link to official doc.

Once that is done, change the origin of the Github repository from HTTPS to SSH.

Then log in to the development Server and switch to the project directory and run this command to change the origin to SSH.

 git remote set-url origin

I have solved the issue using this technique, if there is still a better way and I am sure there is, let me know in the comment or email me.

Further Study


Continuous integration and deployment using Jenkins are super easy and this approach would save a lot of time for developers. They need to just focus on writing better code and Jenkins will do the rest boring stuff.

39 thoughts on “Continuous Integration and deployment (CI/CD Pipeline) with Jenkins and Node.js”

      1. What should i do for angular 4 deployment ..Actually my webapp is build by angular4 and nodejs ..

  1. Thanks for the great article. After reading many other articles, now I seems to get the understanding. I would like to get few advice on process that I would like to create in Jenkins.
    – With Jenkin Build, I would like to create tars/zip of the code for specific environments. Each build tars need to have a specific name.
    – When QA team requires, they can select one of the successful build to be deployed to a specific environment (QA/STG).

    Please let me know how it can be achieved.


    1. Shahid (UnixRoot) Shaikh


      You can do first one using a shell script. As you can see we are writing our build script in shell hence there is chance of putting any kind of relevant code there.

      Second, i am not sure.

    2. For deploying one of the successful build you need to promote the build and pass the parameter for the deployment process. So, then you can choose which build number to deploy.

  2. Hi,

    For second process I use the promoted builds plugin Our build server generates a set of build artifacts (in this case zip files) and the promoted plugin then controls the promotion step of the build. In this case you can have the a step to promote build to QA or STG. I have promotions of DevDeployed, ReadyForQA, QADeployed, PassedQA, and ReleaseCandidate and they all have dependencies to ensure that each promotion is followed. So once build promoted to ReleaseCandidate that is the build that is then deployed to Production with no rebuild.

  3. Did you forget to tell how to configure webhooks in github, github and jenkins are not talking to each other in my setup

  4. What tool is good for deploying nodejs app in a shared server, which dosent have ssh access or nodejs installed

    1. Shahid (UnixRoot) Shaikh

      I don’t think you can deploy Node.js on shared server. If so, please let me know.

  5. Great post!
    Shouldn’t npm be installed on the jenkins server or am I missing something?

    1. Shahid (UnixRoot) Shaikh

      Basically Jenkins server is doing SSH to the Server where application need to run. In that Server NPM should be installed, not needed on Jenkins one.

      1. Well you do run “npm install” and “mocha” to actually test the code (on the Jenkins machine) I’d assume that npm must be installed.

  6. do i need to add the ssh keu if my Jenkins server and development server are the same ?

  7. This line of the deploy script is making my build to fail:

    pm2 restart all

    Throws me this message:

    [PM2] Spawning PM2 daemon with pm2_home=/root/.pm2
    [PM2] PM2 Successfully daemonized
    Restarts are now immutable, to update environment or conf use –update-env
    [PM2][WARN] No process found

    │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │

    Use `pm2 show ` to get more details about an app
    Build step ‘Execute shell’ marked build as failure
    Finished: FAILURE

    1. Shahid (UnixRoot) Shaikh

      Hi there,

      Try to change it to:

      pm2 start app.js OR your server file name
      1. I found that the mistake is to start the app with “node app.js” as you do in the tutorial after the express code, the correct way is like your solution, starting it with pm2 start app.js, other way it will tell there’s no pm2 process.

  8. This is my Console Output in Jenkins after run the Task, I set in the Shell Script of the Task:
    SAMPLE unit test
    1) should return home page
    double callback!
    0 passing (42ms)
    1 failing
    1) SAMPLE unit test should return home page:
    Uncaught TypeError: Cannot read property ‘status’ of null

    The error is pointing me in to this line :

    You know why is that, is that Ok?

    1. Shahid (UnixRoot) Shaikh

      Please make sure that your Application server is running when the build process is going on.

  9. Thanks for this very nice tutorial. I have some problems in the last step:

    + ./deploy
    Pseudo-terminal will not be allocated because stdin is not a terminal.
    Host key verification failed.
    Build step ‘Execute shell’ marked build as failure
    Finished: FAILURE

    Could you help me ?. ty

    1. Okay I figured it out! I realize this is old, but someone might fight it. I realized after hating my life whenever I have to do devops that I should just always write down everything I do until it works and then every time I do the thing again modify the steps until I fully understand.

      What was wrong in my case was that I had to do

      sudo su; su jenkins

      to become the jenkins user and then connect to the new server as jenkins

      ssh jenkins@new-server

      in the terminal before jenkins could do it on its own

  10. Hi, Great article shahid. One question if we are deploying inside a windows server what will be the content of deploy file.

    1. Shahid (UnixRoot) Shaikh

      Good question. I am really not a Windows user.

      Hope someone replies on it.

    2. I would guess you could use a .bat file, you might need ssh access on the windows server for jenkins to connect also. Freessh is what I have used before. Good article too op.

  11. Hello i have one problem i added one nodejs application to jenkins from git repository but if i m trying to build that app server started but the build doesn’t stop can you please help me out how to resolve this issue..?

  12. Useful article! Could you please tell me if you have used SonarQube integration with angular projects?

  13. Hi Shahid, Great Article. But what if several commits are made back to back? I want something that could run mocha tests parallely. Can you help me with that?

    1. Shahid (UnixRoot) Shaikh

      Github will trigger webhook request for each commit. You can run any test in the sequence of commands.

  14. I want the build in the form of war file to push it to the version control system, how can I do it ?

  15. i have issue with this part ssh userName@development-ip
    I am unable to login to development server , its just showing this error.
    ssh: Could not resolve hostname [hostname]

  16. Wow!! very well articulated.
    Very help full. Thankssss!!!

    How about NodeJs integration tests integrated with Jenkins?
    In that case, all we need to do is a shell script, which will do the typical ‘npm test test/Integration.js’?

    Is there any good integration framework for nodejs?

  17. Hi, really good, it helped me a lot!
    I’ve got a question: Is it possible to package a nodeJs app in a RPM file and then to use jenkins to deploy it?
    I’ve take this idea from nebula-ospackage project.
    Thanks in advance!

  18. I have done upto npm install and npm run build command. my folder is creating in jenkin home directory. but I cant find how go in ./dist folder and how to configure npm start command in jenkin..thanks

Comments are closed.