In this guide, we will see how to setup Jenkins in different servers as master and slave. We will use docker to quickly run the Jenkins within the container and establish master slave communication between both servers.

Having Jenkins master and slaves as Docker containers can be a very useful as it will be portable, easily extendable, isolated from other processes, easy to keep it maintainable, and resource efficient.

For this guide, I will use two Linux servers both running Debian 10 and docker with docker compose. I will use one server (server1) as master and another as slave (server2)

Installing docker & docker compose in both Linux servers

We will install docker with easy installation script

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

After installation, make sure to add yourself to docker user group

For docker compose installation, please refer the docker compose installation guide

Installing Jenkins on servers

I’ve prepared a docker-compose file which takes care all the necessary steps to deploy Jenkins in a container. In both servers, paste the below code in docker-compose.yml file and save

version: '3'
services:
  jenkins:
    image: jenkins/jenkins:lts
    volumes:
      - jenkins_home:/var/jenkins_home
    ports:
      - "8080:8080"
      - "50000:50000"
      - "5000:5000"
    container_name: jenkins_container
volumes:
    jenkins_home:

I used persistent mount where our workspace and all the Jenkins data will live in jenkins_home volume.

Now run the below command in both servers in order to deploy the Jenkins

docker-compose up -d

Setting up Jenkins

After installing Jenkins, the docker container will be prepared within a minute. Now if you see the container log, you should see a password is generated which is required to setting up the Jenkins.

docker container ls
docker container logs jenkins_container

Note the password.

<img class="alignnone size-full wp-image-572" src="/uploads/2020/06/jenkins_1.png" alt="" width="990" height="154" srcset="/uploads/2020/06/jenkins_1.png 990w, /uploads/2020/06/jenkins_1-768x119.png 768w" sizes="(max-width: 990px) 100vw, 990px" />

Now visit http://your-server-ip:8080 and begin the installation process

Setting up master and slave node

Now that we have installed and prepared Jenkins in both servers, let’s prepare server1 as master and server2 as slave node

In server1, click “Manage Jenkins” and then “Manage Nodes And Clouds” -> “New Node”

<img class="alignnone size-full wp-image-573" src="/uploads/2020/06/jenkins_2.png" alt="" width="1013" height="694" srcset="/uploads/2020/06/jenkins_2.png 1013w, /uploads/2020/06/jenkins_2-768x526.png 768w" sizes="(max-width: 1013px) 100vw, 1013px" /> <img class="alignnone size-full wp-image-574" src="/uploads/2020/06/jenkins_3.png" alt="" width="1261" height="767" srcset="/uploads/2020/06/jenkins_3.png 1261w, /uploads/2020/06/jenkins_3-768x467.png 768w" sizes="(max-width: 1261px) 100vw, 1261px" />

<img class="alignnone size-full wp-image-575" src="/uploads/2020/06/jenkins_4.png" alt="" width="1058" height="742" srcset="/uploads/2020/06/jenkins_4.png 1058w, /uploads/2020/06/jenkins_4-768x539.png 768w" sizes="(max-width: 1058px) 100vw, 1058px" />

We provided a node name and make that node permanent. Click Ok

<img class="alignnone size-full wp-image-576" src="/uploads/2020/06/jenkins_5.png" alt="" width="1187" height="610" srcset="/uploads/2020/06/jenkins_5.png 1187w, /uploads/2020/06/jenkins_5-768x395.png 768w" sizes="(max-width: 1187px) 100vw, 1187px" />

Now we will setup the slave node as follows:

Name: Name of the slave

Description : Optional , Description for the slave node

# of executors : The maximum number of concurrent builds that Jenkins may perform on this agent.

Remote root directory: /var/jenkins_home This directory is the dedicated Jenkins directory in the docker container. So don’t change it

Labels: Labels (or tags) are used to group multiple agents into one logical group. We can use that label/tag to specify the job to build in that node

Usage: Only build jobs with label expressions matching this node

Launch method: Launch agent by connecting it to the master. We will use this method to sync master slave communication

<img class="alignnone size-full wp-image-577" src="/uploads/2020/06/jenkins_6.png" alt="" width="1911" height="932" srcset="/uploads/2020/06/jenkins_6.png 1911w, /uploads/2020/06/jenkins_6-768x375.png 768w, /uploads/2020/06/jenkins_6-1536x749.png 1536w" sizes="(max-width: 1911px) 100vw, 1911px" />

Now after clicking save, click on the slave node
<img class="alignnone size-full wp-image-579" src="/uploads/2020/06/jenkins_7.png" alt="" width="1197" height="628" srcset="/uploads/2020/06/jenkins_7.png 1197w, /uploads/2020/06/jenkins_7-768x403.png 768w" sizes="(max-width: 1197px) 100vw, 1197px" />

Here we will see the way of connecting with master server from slave. We need the agent.jar file. So copy the agent.jar address (right click on agent.jar and click copy the address) and paste it to the notepad. Don’t delete the tab

<img class="alignnone size-full wp-image-580" src="/uploads/2020/06/jenkins_8.png" alt="" width="1438" height="730" srcset="/uploads/2020/06/jenkins_8.png 1438w, /uploads/2020/06/jenkins_8-768x390.png 768w" sizes="(max-width: 1438px) 100vw, 1438px" />

Now login to server2, note the container name and ssh into the Jenkins container

docker container ls
docker container exec -it jenkins_container bash

After that you should see you are in Jenkins container. Now navigate to Jenkins home directory and use wget command to pull the agent.jar file from server1 (we copied the agent.jar file address from server1)

cd /var/jenkins_home
wget http://server1-address:8080/jnlpJars/agent.jar

Now navigate to the browser tab and copy any of the agent command. I choose the second one

<img class="alignnone size-full wp-image-581" src="/uploads/2020/06/jenkins_9.png" alt="" width="1503" height="710" srcset="/uploads/2020/06/jenkins_9.png 1503w, /uploads/2020/06/jenkins_9-768x363.png 768w" sizes="(max-width: 1503px) 100vw, 1503px" />

Now get back to the terminal (where you are ssh into jenkins slave container) and paste the command. Hit enter. A few seconds later, you should see INFO: Connected. Which means our slave node is successfully connected with master node.
<img class="alignnone size-full wp-image-582" src="/uploads/2020/06/jenkins_10.png" alt="" width="885" height="395" srcset="/uploads/2020/06/jenkins_10.png 885w, /uploads/2020/06/jenkins_10-768x343.png 768w" sizes="(max-width: 885px) 100vw, 885px" />

Go back to the browser tab and hit refresh. You should see “Agent is connected.” message

<img class="alignnone size-full wp-image-583" src="/uploads/2020/06/jenkins_11.png" alt="" width="1059" height="594" srcset="/uploads/2020/06/jenkins_11.png 1059w, /uploads/2020/06/jenkins_11-768x431.png 768w" sizes="(max-width: 1059px) 100vw, 1059px" />

Testing a build job to our slave node

Let’s see how we can build a job to our slave node. First create a very simple job in our master server

<img class="alignnone size-full wp-image-585" src="/uploads/2020/06/jenkins_12.png" alt="" width="1295" height="755" srcset="/uploads/2020/06/jenkins_12.png 1295w, /uploads/2020/06/jenkins_12-768x448.png 768w" sizes="(max-width: 1295px) 100vw, 1295px" />

Under “General” settings, select “Restrict where this project can be run” and put your slave node’s label. In my case it is “linux_node”.

<img class="alignnone size-full wp-image-586" src="/uploads/2020/06/jenkins_13.png" alt="" width="1392" height="468" srcset="/uploads/2020/06/jenkins_13.png 1392w, /uploads/2020/06/jenkins_13-768x258.png 768w" sizes="(max-width: 1392px) 100vw, 1392px" />

Now in Build section, I selected bash command in order to echo a text. Just to test it out whether our build works on slave node or not. Click save.

<img class="alignnone size-full wp-image-587" src="/uploads/2020/06/jenkins_14.png" alt="" width="1061" height="760" srcset="/uploads/2020/06/jenkins_14.png 1061w, /uploads/2020/06/jenkins_14-768x550.png 768w" sizes="(max-width: 1061px) 100vw, 1061px" />

Now click on the “Build Now” and then click on the build number. Click on the “Console Output”

<img class="alignnone size-full wp-image-588" src="/uploads/2020/06/jenkins_15.png" alt="" width="1667" height="690" srcset="/uploads/2020/06/jenkins_15.png 1667w, /uploads/2020/06/jenkins_15-768x318.png 768w, /uploads/2020/06/jenkins_15-1536x636.png 1536w" sizes="(max-width: 1667px) 100vw, 1667px" />

<img class="alignnone size-full wp-image-589" src="/uploads/2020/06/jenkins_16.png" alt="" width="1307" height="679" srcset="/uploads/2020/06/jenkins_16.png 1307w, /uploads/2020/06/jenkins_16-768x399.png 768w" sizes="(max-width: 1307px) 100vw, 1307px" />

<img class="alignnone size-full wp-image-590" src="/uploads/2020/06/jenkins_17.png" alt="" width="1228" height="548" srcset="/uploads/2020/06/jenkins_17.png 1228w, /uploads/2020/06/jenkins_17-768x343.png 768w" sizes="(max-width: 1228px) 100vw, 1228px" />

You should see that the build is success. It executes our desire command in the slave node without any issue

<img class="alignnone size-full wp-image-591" src="/uploads/2020/06/jenkins_18.png" alt="" width="1290" height="548" srcset="/uploads/2020/06/jenkins_18.png 1290w, /uploads/2020/06/jenkins_18-768x326.png 768w" sizes="(max-width: 1290px) 100vw, 1290px" />

We successfully setup a master and slave node. Similarly we can add more slave node to the master server and build our specific job to the specific node based on the label.