How to Setup Docker containers as Build Slaves for Jenkins

Docker containers as Build Slaves for jenkins jobs

In a distributed Jenkins environment, resource utilization of the slaves will be very less when the builds are not quite often. In this scenario, it is better to use ephemeral docker containers as your build slaves for better resource utilization. As we all know that spinning up a new container takes less than a minute. So, for every build a new container will get spun up, builds the project and will get destroyed.

Docker containers as Build Slaves

In this guide, I will walk you through the steps for configuring docker container as build slaves.

I assume that you have a Jenkins server up and running. If you do not have one, follow this tutorial. How to setup jenkins 2

Let’s Implement It

The first thing we should do is set up a docker host. Jenkins server will connect to this host for spinning up the slave containers. I am going to use Ubuntu 14.04 server as my docker host.

Configure a Docker Host

1. Spin up a VM, and install docker on it. You can follow the official documentation for installing docker. 

2. Jenkins master connects to the docker host using REST API’s. So we need to enable the remote API for our docker host. Follow enabling docker remote API tutorial.

Once you enabled and tested the API, you can now start configuring the Jenkins server.

Create a Jenkins Slave Docker Image

Next step is to create a slave image. The image should contain the following minimum configurations to act as a slave.

1. sshd service running on port 22.

2. Jenkins user with password.

READ  Cloud Based Docker Container Monitoring Using Datadog

3. All the required application dependencies for the build. For example, for a java maven project, you need to have git, java, and maven installed on the image.

I have created a Jenkins image for maven. You can use this image or use its Dockerfile a reference for creating your own.

Make sure sshd service is running and can be logged into the containers using a username and password. Otherwise, Jenkins will not be able to start the build process.

Configure Jenkins Server

1. Head over to Jenkins Dashboard –> Manage jenkins –> Manage Plugins.

2. Under available tab, search for “Docker Plugin” and install it.

3. Once installed, head over to jenkins Dashboard –> Manage jenkins –>Configure system.

4. Under “Configure System”, if you scroll down, there will be a section named “cloud” at the last. There you can fill out the docker host parameters for spinning up the slaves.

5. Under docker, you need to fill out the details as shown in the image below.

Note: Replace “Docker URL” with your docker host IP. You can use the “Test connection” to test if jenkins is able to connect to the docker host.

jenkins docker plugin configuration

5. Now, from “Add Docker Template” dropdown, click “docker template” and fill in the details based on the explanation and the image given below.

Docker Image – Image that you created for the slave.

Remote Filing System Root – Home folder for the user you have created. In our case it’s jenkins.

Labels – Identification for the docker host. It will be used in the Job configuration.

READ  How to Install and Configure Jenkins 2 on centos/Redhat Servers

Credentials – click add and enter the username and password that you have created for the docker image. Leave the rest of the configuration as shown in the image below and click save.

dcoker slave image config

Building Jobs on Docker Slaves

Now that you have the slave configurations ready, you can create a job, select “Restrict where this project can be run” option and select the docker host as slave using the label as shown below.

docker slave job configuration on jenkins

If you have done all the configurations right, Jenkins will spin up a container, builds the project and destroys the container once the build is done. You can check the build logs in your jobs console output.

Free DevOps Resources

Get DevOps news, tutorials and resources in your inbox. A perfect way If you want to get started with devops. Like you, we dont like spam.

25 comments

  1. cpeng Reply

    Thank you for the great tutorial. I was wondering is it possible to archive artifacts built in Docker container in Jenkins? i.e. after the build completes, I go to Jenkins, click on the build run and download the build artifacts. Thanks!

    • Devopscube Reply

      @disqus_sF63zwkuVN:disqus you can use nexus configuration to upload the artifacts to nexus. So after a successfull build, your artifact would automatically gets uploaded to nexus.

  2. Ramp Reply

    Great! Nice tutorial. Any good idea on how to copy the compiled files over to Jenkins workspace ?

    • Bibin Wilson Post authorReply

      HI Ramp,

      Yes. You can mount the jenkins workspace as a volume to the Docker slave. In your scripts running inside the container, you can write the logic to copy the compiled files before termination.

  3. Arun Reply

    Hi Bibin, will it auto create the slave and destroy it after the build. What if the docker slave is created successfully and the build fails (Maven/Gradle or any jenkins job related configuration/build/etc step fails? etc).

  4. Prasenjit Dutta Reply

    How to get the docker url….i tried with http://:2375, but connection is failing…..could you please suggest, whether wrong with the port number? if so , please let me know how can i get the port number

  5. Prasenjit Dutta Reply

    Hi Bibin,

    I tried all possible ways, when after configuration i start the docker as process, it gets connected with the jenkin, but the docker daemon thread doesn’t get up and thus any docker command dosn’t executes.

    But when restarts the docker machine as daemon, the changes doesnot reflects and thus connectivity fails.

    Could you please provide some input on this.

    Thanks,
    Prasenjit

  6. Prasenjit Dutta Reply

    Bibin,

    I am able to create the image now, but the container is not spinning with plugins, could you please let me know which plugin to be used to spin the container?

    Thanks,
    Prasenjit

  7. Prasenjit Dutta Reply

    I am able to create the image now, but the container is not spinning with any of the plugins, could you please let me know which plugin to be used to spin the container?

  8. nancy Reply

    Hi Bibin, How to make auto created slave container won’t destroy after the job finished?

    • Bibin Wilson Post authorReply

      Hi Nancy,

      The plugin is made that way to destroy the containers. You can commit the containers if you would like to persist them. Please go the plugin documentation. There it it mentioned clearly.

  9. Prasenjit Reply

    Hi Bibin,

    I already tried this, this step is creating the image, but not spinning the containers.

    Thanks,
    Prasenjit

  10. parma Reply

    hi,
    i am not able to build the job in docker it keeps the job in queue
    it shows “(pending—All nodes of label ‘docker-slave’ are offline)” even if the container is running and ssh service is starded

  11. rahul pandey Reply

    hi bibin,
    i have configured all as u mentioned above.
    but when i build the job its remians in queue.
    can u guide me in this???

  12. Thilak Reply

    Hi,

    I would be grateful to hear an answer for the following post.

    I have a docker running on my host, and have a container with jenkins running on it. There are other containers, say a1,a2,etc running parallely. Now, i would like to spin up a container (say C1 )for a build. C1 now has to spin up the containers a1,a2 within it. I understand that there must be a docker within C1. Can this be achieved using Jenkins docker plugin ?
    Also, i assume i need not expose any TCP socket, since i have jenkins running on the same host. Please explain the solution in detail.
    Thanks a ton,
    Thilak

  13. darko Reply

    Hi Bibin,

    with one colleague of mine we put in place a similar process, the only issue for me is to connect to the agent/container created by my job.
    When I look at the logs I can see that the connection is refused due the port used by jenkins is not matching the port that we binded with the port 22 exposed from the container.
    the strange part is that jenkins is incrementing the port used by 1 everytime a container is created.
    Does this ring a bell for you or do you have any suggestion?

    Many thanks,
    Darko

  14. Pingback: How to Setup Docker containers as Build Slaves for Jenkins – DevOps Infographics Resource Center – Programming and IT

  15. dtothefp Reply

    Thanks for the post. I’m curious of how this works with a workflow where the repos you want to test/build in CI are actually managed by docker. I’ve messed around on a jenkins-master that I scaled up using Docker, and exposed the Docker socket on the host to the CI container, allowing me to run docker commands inside my builds that were running on jenkins-master.

    Now that I’m running builds inside Docker containers on a remote host I’m wondering what the preferred method for doing this would be. I’ve seen explanations of Docker-in-Docker vs. Docker-outside-of-Docker, and I’m unsure what is the better approach? I’m assuming that my Docker container that is equivalent of bibinwilson/jenkins-slave could either expose the Docker socket to the CI build or could somehow install Docker inside the container. Are there best practices here or am I thinking about it all wrong?

  16. mayank Reply

    hi,

    i created a docker image but jenkins is not able to log into that container image that showing
    “pending—All nodes of label ‘docker-slave’ are offline)” onjenkins log

    pleas help me

Leave a Reply

Your email address will not be published. Required fields are marked *