How to Setup Docker containers as Build Slaves for Jenkins

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.

You Might LikeLearn Docker Technologies for DevOps and Developers

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

If you want docker based jenkins setup, you can follow this tutorial -> Setup Jenkins On a Docker container

READ  How to Setup AWS ECS Cluster as Build Slave for Jenkins

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.

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.

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.

43 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.

        • JALPA MODASIYA Reply

          Is there a way to commit container when we use multibranch pipeline project

  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

  17. Fadi Reply

    This is the exact setup that I have, which works pretty well. It would be great to show a tutorial on how to have this run in a docker swarm setup (so basically same thing but show how to properly configure the docker swarm to make it work properly with Jenkins).

  18. kirankumar reddy Reply

    i followed same as given and when trigger the build showing
    ” #1 (pending—Jenkins doesn’t have label docker-slave) “.

    Please guide me regarding this.

  19. dtothefp Reply

    This works but I guess I assumed if a second job was triggered while a job is currently running, it would run a new slave. What I actually see is a single slave is started, if a second build is triggered while the first is still running, it tries to wait for/run on the same slave. When the first build finishes, the slave is torn down, the second job restarts on a different slave and runs.

    Is there anyway to run multiple slaves on the same host?

    • Mohit Reply

      Hi dtothefp,
      I am facing the same issue. Did you found out the solution to your problem?

  20. divanov Reply

    Thanks for this blog, it helped me setup my Jenkins-Docker environment. Though I am trying to figure out a way to retain the containers if the build fails. The idea is to troubleshoot the failure. Is there a way to do it ?

  21. venkatesh Reply

    Hi Bibin,

    How can we spin a multiple containers for a single jenkins job.

  22. ETeodorus Reply

    Hi Bibin,

    How can I build pipeline jobs on Docker Slaves once this kind of job there’s no “Restrict where this project can be run” option to select and set the label restriction? In my environment I have physical slaves and docker slaves, but without that option, all jobs run in the physical slave.

  23. Jim Zucker Reply

    Hi, I looked @ your slave docker image, would you mind sharing the dockerfile that created it?

  24. Arnold Reply

    Hi Bibin,
    If this does work will the slave appear under the Jenkins nodes on the master?

    Thanks.

    • Bibin Wilson Post authorReply

      Hi Arnold,

      Docker containers will get spun up on the go and gets destroyed after the build. So I don’t think it will be listed in the node list.

  25. Mohamed Reply

    Helpful Article !!. Bibin, Can you make an article how to upgrade Jenkins which is in HA cluster. I tried to do some research but I couldn’t find any articles about this. You are making a crystal clear overview , it can help lots of people

  26. ravi_s Reply

    Hi All,
    I am running multiple docker servers running 300+ jobs. If one server goes down i have observed all other servers will go offline. Any idea on this?

  27. Kelly Reply

    Hi Arnold,

    I just found the docker containers node can be saved. From manage jenkins. –>. configure system –> Cloud —> docker template —> Availability, select “Experimental: Keep this agent online as much as possible”.

Leave a Reply

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