Table of Contents generated with DocToc

Jenkins is a great open source continuous integration server that can automate tasks such as testing, linting, building and deploying software projects. This guide will show you how easy it is to set up your own containerized Jenkins server on AWS EC2. A Jenkins CI server can be used with practically any type of software project, however we will focus on using it with a Node.js project.

In addition to running Jenkins inside a highly portable container, this guide will show you how to set up your tests to run inside containers as well. Testing with containers is the best way to guarantee testing consistency and portability.

This guide will cover configuring Jenkins to provide:

  • - GitHub integration (hooks, badges)
  • - Code coverage reporting
  • - Test running and commit status reporting
  • - Automated docker builds and publishing to the docker registry

This guide will also use a sample Node.js project simple-producer-consumer

This project uses istanbul for code coverage analysis and mocha for a test runner.

Part 1: Configuring an EC2 Server

First you will need to sign up for an AWS account. When you’re ready create a new server using AWS EC2. Step 1 of the EC2 launch wizard will ask you to select an AMI to base your server on. You can select any linux based AMI you wish that supports Docker. I recommend CoreOS since it is distributed with the Docker engine already installed.

In this tutorial we’re going to use CoreOS-stable-766.5.0-hvm - ami-00ebfc61.


Step 2 will prompt you to select an instance type. I recommend t2.small as 1gb of memory provided by t2.micro may not be enough for heavier CI build tasks.


Skip ahead to step 4 to select how much disk space you instance will have. I recommend 15-20gb.


Next go to step 6 to configure your instance’s security groups. Make sure your instance has TCP inbound traffic on ports 22(ssh) and 80(http) open to the internet. Finally, you can click Review and Launch and then Launch to start your server. Make sure you select an public/private key pair and make sure you have the private key on your development machine so you can SSH into your server.


Part 2: Configuring Jenkins in a Docker Container on your EC2 Server

For this next part you will need to be able to ssh into your EC2 server. Assuming you properly set up your keypair you should see a similar message to this when you log in.

~ ❯❯❯ ssh core@
Last login: Sat Mar  5 04:40:50 2016 from
CoreOS stable (835.13.0)
core@ip-172-31-12-16 ~ $

Create a directory to serve as your jenkins home directory. This is where Jenkins will store your server configuration, build artifacts, checked out repository code, etc. You will also want to the owner to be your jenkins user.

core@ip-172-31-12-16 ~ $ mkdir ~/jenkins_home
core@ip-172-31-12-16 ~ $ chown -R 1000 ~/jenkins_home

We’re going to create a docker image based on the official jenkins image in docker hub.

Official Jenkins Docker Image:

Create a file ~/Dockerfile and paste in the following contents:

FROM jenkins:1.642.1
USER root
RUN mkdir /var/log/jenkins
RUN chown -R jenkins:jenkins /var/log/jenkins
ENV JENKINS_OPTS="--logfile=/var/log/jenkins/jenkins.log"

The above docker commands create a directory and configures Jenkins to store its logs in that directory.

Run the command docker build -t myjenkins . to build an image from your Dockerfile. The -t myjenkins flag instructs docker to name the image “myjenkins”.

Now we’re ready to create and start a container from the image we just built that will serve Jenkins. Run the following command:

$ docker run \
-p 80:8080 \
--name=jenkins-master \
-v $(which docker):/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/lib/ \
-v /home/core/jenkins_home:/var/jenkins_home:rw \
-d myjenkins

Here’s a breakdown of what the above command is doing.

  • -p 80:8080 This instructs Docker to bind the host port 80 to the container port 8080. The official Jenkins image is configured to listen on the root network interface inside the container on port 8080. Binding the host port 80 to port 8080 will allow browsers to make HTTP requests to your jenkins server without specifying a port in the url.

  • --name=jenkins-master The name docker will assign to your container.

  • -v $(which docker):/bin/docker This mounts the host machine’s docker binary inside the container where it will be available in the container’s $PATH.

  • -v /var/run/docker.sock:/var/run/docker.sock Mounts the host machine’s socket that the docker daemon is listening on inside the container. The container will be able to communicate with the same docker daemon as the host machine.

  • v /usr/lib/ Mounts a library that is required by the docker binary.

  • -v /home/core/jenkins_home:/var/jenkins_home:rw Mounts the Jenkins home directory as a shared volume inside the container. By mounting the directory as a shared volume, you wont lose your Jenkins confuration or build artifacts if you delete your Docker container.

  • -d myjenkins Instructs docker to run the container in the background (as a daemon) and create it from the image “myjenkins”

You should now have a running Jenkins server that you can access from your browser! Go ahead and try it out.


Part 3: Configuring Jenkins Settings

Security and Access Control

Step 1

Open Jenkin’s security configuration page. jenkins_config_step_1

Step 2

Enable security and enable Jenkin’s own user database. jenkins_config_step_2

Step 3

Create an administrator account. jenkins_config_step_3

Step 4

Prevent anonymous users from creating new accounts and enable administrator privileges on your account. jenkins_config_step_4

Adding Plugins

Open Jenkin’s plugin configuration page. jenkins_config_step_5

Open the available plugins tab and select the following plugins to install:

  • - Clover Plugin
  • - Embeddable Build Status Plugin
  • - GitHub Plugin

After clicking “Install without restart” check the box “Restart Jenkins when install is complete and no jobs are running” jenkins_config_step_6 Once Jenkins finishes installing and restarts you will have all the plugins required for this tutorial. The plugins will modify Jenkins menus and configuration options.

Part 4: Adding a Job

Now that we have Jenkins fully set up, we’re ready to add our first Job. Jobs in Jenkins are sets of tasks to run either on demand or in response to events, such as a push to a repository. Actual runs of Jobs are referred to as “builds.”

For our job, we’re going to use the repository cflynn07/simple-producer-consumer. The GitHub plugin will automatically set up the hooks to receive notifications from GitHub. For every push to the repo Jenkins will: 1. Check out the latest code from GitHub into a directory on your server’s file system 2. Start a Docker container with a command to install the project’s dependencies and run the tests 3. Report the build status (whether or not the container exit code was 0) for the commit that triggered the build to GitHub 4. Generate Clover coverage reports from the clover.xml file produced by the test runner