Jenkins Master and Slaves as Docker Containers

at in tutorials

TL;DR

WHAT: We are going to use Docker Plugin to connect Jenkins to Docker installed in a VM and run stages or entire pipelines inside containers.

HOW: In order to do that, we will need to have a Jenkins up and running, a host for your Docker containers accessible through API, slave build agent images, and install and configure the Docker plugin.

The files used in this tutorial can be found in github.com/n3xu5/jenkins-docker-setup.


CI/CD is great and all but it can add new layers of complexity to your flow. Properly manage build agents, for instance, can easily become very complex with different environments for each of the stages and very specific needs in all of them. This can be a daunting task.

Having Jenkins slaves as Docker containers can be a very useful tool, in this case, portable, lightweight, easily extendable, easy to keep it organized, resource efficient just to name a few.

So, let’s get started!

1. Jenkins Up And Running

It is safe to assume by now you have Jenkins up and running as a Docker container, but if you don’t, don’t panic I am here to help.

You can either go to Jenkins documentation and follow their detailed install instructions or you can use this docker-compose file and have it with this command:

docker-compose up

If you choose to use the later please be sure to not use -d, so you can fetch the auto-generated admin password that will be shown in the output.

2. Host For Your Docker Slave Containers Accessible Through API

We need a separate host with Docker installed that will handle our Docker slaves. For this tutorial, we will use this Vagrant box with Ubuntu 16.04.

Note that we fixated the IP.

config.vm.network "private_network", ip: "192.168.50.4"

Install Docker in the VM, since we are on Ubuntu you can do it very easily with:

apt-get install -y docker.io

Now you need to enable Docker remote API, and you can find detailed info on how to do it here.

Remember that to be able to access Docker from outside the VM you need to point to the fixed IP you’ve set in the previous step, so in this case would be something like this:

curl 192.168.50.4:4243/version 

3. Create Slaves Images

Now we have a Jenkins, the host that will handle our build agents, it is time to create the images. You can choose between different launch methods to spin up this build agent, each of them requires a minimum amount of setup to be able to work, here we will focus on agents being launched using ssh method.

You can create one from scratch, and that will require SSHD, JDK installed, and a user called jenkins, or you can use this as basis for a custom image.

This is the bare minimum for a slave build agent image be accessible, you should build upon this and add the tools needed for your project.

Here is an example of a very simple image that handles Composer dependencies and performs unit tests in PHP projects.

FROM jenkins/ssh-slave

# Install selected extensions and other stuff
RUN apt-get update \
    && apt-get -y --no-install-recommends install \
    php7.0-cli \
    php-xdebug \ 
    composer \
    phpunit \
    && apt-get clean; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*

After you successfully built your images tag and push them to your registry, in this case, I used Docker Hub.

4. Install & Configure the Docker Plugin

Install Docker plugin on the plugins manager page, accessible through Jenkins Dashboard > Manage Jenkins > Manage Plugins.

Configuring Docker Plugin

1. Cloud

Add a new Cloud going to Jenkins Dashboard > Manage Jenkins > Configure System at the end of the page. It will show up the fields needed to connect to Docker host, our previously created VM, so give it a name and fill in the details, will be something like this:

Configure Docker Plugin Step - 1 - Access

Use the Test Connection button at the right to be sure everything is as it should be, it will write something like this on its side:

Version = 1.13.1, API Version = 1.26

2. Docker Agent Templates

Add a new Docker Agent Template it is used to parameterize your image. Here is a list of the crucial parameters needed.

  • Labels: How you will identify this image in your pipelines.
  • Docker image: The name of the image related to this template.
  • Registry Authentication: The credentials used to log in to your registry account.
  • Remote Filing System Root: The home folder for the user we’ve created in the image, in this case, jenkins.
  • Connect Method: Select “Connect with SSH” which our images were built to be accessed with.
  • User: Name of the user used to connect, so, jenkins.

Configure Docker Plugin Step - 2 - Agent Templates

5. Examples Of Use

Now that everything is set to update your pipelines to use the containers, simply point out to the right labels that match the ones you put in the Docker Agent Template configuration like this:

pipeline {
    agent { label 'php' }
    stages {
        stage("Build") {
        //...
        }
    }
}

Or if you want a different container for each step:

pipeline {
    stages {
        stage("Build") {
            agent { label 'php-build' }
            //...
        }

        stage("Test") {
            agent { label 'php-test' }
            //...
        }
    }
}

This offers a lot of new options of how to handle your pipelines and hopefully will speed up the processes.

Have fun :)



See Also