in Jenkins Apache Node bitbucket git bash ssh web server web development digital ocean linux ubuntu java ~ read.

Setting Up Continuous Integration With Jenkins for Nodejs Applications

In this post we are going to walk you through how to set up continuous integration with Jenkins for a Nodejs application.

What is Continuous Integration?

Continuous Integration (CI) is a development practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early.

In a rather simple term, let's image a story that developers have to deal with without CI. Let's say Tom just finished his job today and push the code to the server. But once he pushed the code he has to build the whole project and run the tests manually. Imagines that situation for every developer which is gonna take up a lot of time and error prone. CI is just like a butler that takes care of this stuff for developers. And among these tools, Jenkins is most popular one.

Let's create a Jenkins server.

We will create a droplet in Digital Ocean that will solely build our applications.

You might ask that why do you need a separated server for Jenkins? Could we put them together?
As for the best practice is to have a separate machine for Jenkins-Server, and not to use it for builds at all.

A build-machine should have a predefined configuration, and Jenkins should not be part of it. (Jenkins requirements may even conflict with those of the build-machine) You should be able to boot / clone / upgrade / restore / trash the build-machine without any impact on Jenkins.

1. Create a Ubuntu server with Nodejs installed

First we need to get over to Digital Ocean and choose the one similar like the following.

And choose a nodejs one click

Next you will receive an email informing your password. If you are a windows user, please use Putty to ssh into your server. If you are Mac/Linux user please just use your terminal. Run the following command.

ssh root@YOUR_IP_ADDRESS

(replace YOUR_IP_ADDRESS to the ip address of your server)

Since using root all the time is not secure since its ability to execute all commands. Let's create a normal user. Please run the following command.

adduser admin usermod -a -G sudo admin

Log off as root and login as the newly created admin.

2. Let's install Jenkins

Since Jenkins require Java installed to operate. Let's install Java first. Run the following command.

sudo apt-get install openjdk-7-jre

follow by the following command

sudo apt-get install openjdk-7-jdk

Next you can run java --version to check whether you installed it correctly.

Next let's install Jenkins by running the following commands.

First we need to add the Jenkins key into our server.
wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -

Next we will add Jenkin into our sources list.
sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'

Install Jenkins
sudo apt-get update sudo apt-get install jenkins

After you finish the installation please head over to YOU_IP_ADDRESS:8080 to check whether you can see Jenkins home page.

3. Let's make our Jenkins more secure.

As you know that by default Jenkins allow every to get into their home page which is not cool. So let's create some users for login.

Step 1 - Click on Manage Jenkins and choose the ‘Configure Global Security’ option.

Step 2 - Click on Enable Security option. As an example, let’s assume that we want Jenkins to maintain it’s own database of users, so in the Security Realm, choose the option of ‘Jenkins’ own user database’ and unselect the ‘Allow users to sign up’ option.

Step 3 − You will be prompted to add your first user. As an example, we are setting up an admin users for the system.

Now that is pretty much it. You are done at the moment for setting up Jenkins. Good job!

Create a Nodejs sample application.

What we need to do next is to create a sample NodeJs application.

1. Use express to quickly generator Nodejs App

We will use [Express Generator] to get it done quickly.

Install globally
npm install express-generator -g

Check whether you installed it correctly
express -h

Create your app
express myapp

Cd into the application and install all the dependencies
cd myapp npm install

Install forever.

[sudo] npm install forever -g

Run the application
forever start ./bin/www

Now head over to localhost:3000 to check the result like the following.

2. Let's set up a Git repository for Bitbucket

Nice, now we have got our sample application running. What we gonna do next is to commit all of our code in to a private Bitbucket repository.

Step 1 - Let's create a Bitbucket account. Head over to their website and register an account.

Step 2 - Next let's create a private empty repository like the following.

Step 3 - Next let's commit our sample code into this private repository.

Run the following command to commit your code locally.

git init

And then we will create a .gitignore file that will ignore the files or directory from Git.

touch .gitignore

And edit it like the following cause we don't want to commit the packages.

node_modules  

(.gitignore)

Next let's do our first commit.

git add -A

First commit message

git commit -m "initial commit"

Next let's generate a key pair for authentication between your computer and Bitbucket repository. Otherwise Bitbucket will ask your username and password all the time!

Run the following command to generate the key

ssh-keygen -t rsa

Next copy the key
cat ~/.ssh/id_rsa.pub

Next go to Bitbucket Settings, SSH Key tab and click add key and give it a name and paste it there.

Cool! Next let's add these code to our Bitbucket private repository.

git remote add origin git@bitbucket.org:welllin/test.git

git push -u origin --all # pushes up the repo and its refs for the first time

git push origin --tags # pushes up any tags

All done. Good job.

Let's create another droplet and use it to host our sample application.

Repeat what we have done before to generate another droplet to host our sample application using Digital Ocean with Nodejs one-click installed.

1. Create a new user

Next we will create a new user. This user would be granted only the privileges to do stuff in the directory /var/www/test. This is a security measure.

sudo adduser --shell /bin/bash --gecos 'Application' test

We will grant privileges:

sudo chown -R test:test /var/www/test/

You can now log in as the ghost user:

su - test

Now we would need to start Ghost:
cd /var/www/test

2. Get the code from Bitbucket and serve it

First let's install Git by the following command.

sudo apt-get update sudo apt-get install git

Remember that since we are using SSH to get into our Bitbucket repository. And this server is just created and Bitbucket repository doesn't have the public key for this server yet. Let's generate the key pair to gain the access.

Run the following command like before.

ssh-keygen -t rsa

cat ~/.ssh/id_rsa.pub

Paste this new key into Bitbucket Settings like we did before.

Next let's cd into the test directory we just created.

cd ~/var/www/test

Let's clone the private repository from Bitbucket using SSH.

git clone git@bitbucket.org:YOUR_NAME/test.git

Next let's install the packages.

npm install

Let's server the app next

DEBUG=myapp:* npm start

Next head over to YOUR_IP_ADDRESS:3000 to check whether you can see the express website.

Next let's connect Jenkins server with App server

Next we are going to connect our Jenkins server with our App server so that each time someone push the code to Bitbucket repository, Jenkins server will update the code in our App server.

1. Create install plugins in Jenkins

First we need to get into our Jenkins server through ssh.

And next we will head over to YOUR_JENKIN_IP_ADDRESS:8080 to Jenkins home page. And click into Manage Jenkins.

Next choose Manage Plugins

Next let's install a plugin called Bitbucket like the following.

Cause I have already got my so the filter result doesn't show up Bitbucket Plugin.

But basically you will go to Available tab and search for Bitbucket then choose Bitbucket plugin then click on Download now and install after restart.

And wait for it to finish.

2. Next let's create a Jenkin project.

Next let's create a Jenbin build project for our sample application.

Next we need to fill up some info regarding the project

There are probably only 6 things you need to take care of at the moment.

Name for your build project - It doesn't matter actually as long as it makes sense.

Source Code Management - Choose Git of cause

Repository URL - This one should be the HTTPS one in your repository page instead of SSH one we used before.

Credentials - This will be the your user name and password etc.

Build Triggers - Check this one Build when a change is pushed to BitBucket

Build - Here you might notice the ./build/deploy. We will use Shell Script to do some automations.

3. Next let's create ssh pair key for App server and Jenkins server

Next we will create a key pair for our App server and Jenkins server.

When Jenkins installs, it creates a new user called jenkins. Jenkins executes all commands with this user, so we need to generate our key with the jenkins user so that it has the appropriate access to it.

While logged in as test on the Jenkins server, execute the following:

sudo su

Provide your test password, and it'll switch you to the root user. Then execute:

su jenkins

Now you are acting as the Jenkins user. Generate an SSH key:

ssh-keygen -t rsa

Save the file in the default location (/var/lib/jenkins/.ssh/id_rsa), and make sure to not use a passphrase (otherwise SSH access will require a password and won't work when automated).

Next, we need to copy the public key that was created. Run this:

cat ~/.ssh/id_rsa.pub

Copy the output. It should be a long string starting with "ssh-rsa" and ending with "jenkins@jenkins-box".

Log out of Jenkins server and log back into our app server as the test user. We need to create a file named authorized_keys in our app user's.ssh folder:

mkdir ~/.ssh nano ~/.ssh/authorized_keys

Paste the public key you copied, and then Ctrl-X/Y/Enter to save and exit. In order for this file to properly work, it needs to have strict permissions set on it:

chmod 700 ~/.ssh chmod 600 ~/.ssh/*

Head back to the Jenkins server, switch to the Jenkins user, and verify that you can login to our app server without entering a password:

ssh test@APP_IP_ADDRESS

You should successfully login to the app server without having to enter the password. With that established, we can now turn to deployment.

4. Add Webhook to our Bitbucket repository

Keep the most of the setting default. One thing you need to care will be URL:

Make sure it is like the following

http://YOUR_JENKINS_IP_ADDRESS:8080/bitbucket-hook/

5. Let's create ./build/deploy shell file

Next go to our local machine. We will add a new file called deploy under build directory.

#!/bin/sh

ssh test@YOUR_SERVER_IP_ADDRESS <<EOF  
  cd /var/www/test
  git pull
  npm install
  forever restartall
  exit
EOF  

Make our new script file executable:

chmod +x ./build/deploy

  1. We login to the App server from Jennkins server using ssh
  2. We cd into where we store our code
  3. We check whether there is update in our Bitbucket repository.
  4. We install npm packages
  5. Next we restart our app using forever
  6. Finally we exit.

Cool! That is pretty much it. Now let's give it a go.

Commit your code and submit it to your Bitbucket repository.

git add . git commit -m 'Test'

Once Bitbucket repository changes, it will tell Jenkins to make a build through Webhook then Jenkins will get into your App server via ssh and trigger another build.

End

Opps it is a rather long post I have to say. But knowing how to use Jenkins to set up Continuous Integration for our project could be quite rewarding in the long run.

As always if you have any opinions or comments please leave it below. Thanks!

comments powered by Disqus