When looking for a hosted continuous integration platform, one problem is that most services don’t support self hosted repositories. I was setting up CI for a team that has git repos on self hosted Gitlab. Jenkins
is a great option for such cases. In this article we’ll set up the following:

Jenkins 2.45 on Ubuntu 16.04
Nginx as reverse proxy for Jenkins
Get an SSL certificate from Letsencrypt
Install Ruby with RVM and Postgres 9.5 for Rails
Run the Rails project’s tests on git push

I’m using a Digital Ocean VPS
with 2GB RAM for this setup. Spin up a VPS with Ubuntu 16.04 and make sure you’re able to SSH as root before continuing.

Although we can access Jenkins on port 8080, it’s always a good idea to enable SSL on a site. The easiest way to do this is to set up Nginx as a reverse proxy to Jenkins, and use an SSL certificate from Let’s Encrypt. Let’s install Nginx:

apt install nginx

SSL with Letsencrypt

We can get a free SSL certificate from Lets Encrypt
. It is as easy as running the following two commands.

$ apt install letsencrypt
$ letsencrypt certonly --webroot -w /var/www/html -d ci.example.com
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/ci.example.com/fullchain.pem. Your
cert will expire on 2017-05-11. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.

Here ci.example.com
should be changed to whatever subdomain you’re using. You can read more about setting up LetsEncrypt SSL certificates here
.

Configure Nginx

Digital Ocean has an excellent tutorial on setting up Nginx as a reverse proxy for Jenkins
. My Nginx conf is based on that tutorial, so please refer to that tutorial if you need to learn more about this config. Change /etc/nginx/sites-enabled/default
to something like below. Replace ci.example.com
with the subdomain you’ll be using.

Now you should be able to access Jenkins on the subdomain using https.

Add public key

Before we set up Jenkins to run our tests, we need to make sure that it has access to our git repo. Create an SSH key pair and copy the public key. You will need to paste it as a deploy key for your project on Github, Gitlab or whichever host you’re using.

At this point, you should be able to git clone the repo when logged in as Jenkins.

Jenkins project configuration

Login to Jenkins dashboard and create a new freestyle project. You will be redirected to the project configuration page. Set the repository URL in the source code management section. In the build section, add a new build step and paste the following:

Save the project, and check that the build is working by clicking the “build now” link.

Now that you have the build working, you need to make sure that a build is triggered whenever someone pushes code or creates a pull request. Our repo is on a self hosted Gitlab installation, so I needed to install the Gitlab plugin on Jenkins and enable the “Build when a change is pushed to GitLab” option. There are plugins available for other services as well.

One minor drawback of Jenkins is cluttered UI. Blue Ocean
is a project aiming to bring a modern UI to Jenkins, and will eventually replace the existing UI. I highly recommend trying out the beta version, which is available as a Jenkins plugin.

Links
Jenkins home page
Blue Ocean
- Modern UI for Jenkins
How To Configure Nginx with SSL as a Reverse Proxy for Jenkins