Jenkins On Docker

Dinesh Velhal
7 min readApr 7, 2019

--

Image by Alexander Kliem from Pixabay

This article is for people who mostly use Windows OS and:

  • Want to learn Jenkins.
  • Want to have a quick local Jenkins setup for Proof of Concept, Exploration or Demonstration purposes.

For them, an obvious first step is to download Jenkins setup for windows and install it as a Windows service. Surely this is the easiest way to have a Jenkins environment for your own practice and exploration on your laptop or desktop. But the ease of installation comes with some key restrictions. See some of the limitations of installing Jenkins directly on Windows:

  • Most of the times, in real life, Jenkins is hosted on Linux/Unix platforms. So learning on Windows would always have limitations.
  • Most commonly used Linux commands or scripts would never work on Windows. Many of them are extensively used while configuring the Pipelines in Jenkins.
  • Key Linux features like pipes, Symbolic links, etc will not be available on Windows

So what’s the way ahead? The answer is easy — Use Docker to host Jenkins!

What is Docker?

Docker is lightweight virtualization technology. In contrast to the virtual machines which run their individual kernels, all containers running on a host OS share the same kernel — the fact that makes them lightweight. Containers are instantiated from the docker images. You can create your own images by composing a Dockerfile or you can download the images from the docker registry hosted at the Docker Hub.

Docker comes in 2 flavors on Windows. First is the Docker Toolbox that is now considered legacy and is the right choice for the older Windows versions & the Windows 10 Home.

For 64bit Windows 10 (Pro, Enterprise and Education editions), Docker for Windows is the best choice and a detailed installation guide can be found here. Please get it installed. This article is based on the Docker for Windows version.

A couple of things to note here:

  • You need elevated privileges (Admin privileges) to run Docker on Windows.
  • If you are inside a corporate network you may need to raise a support ticket to get Docker downloaded and installed.

After successful installation, you will be able to see the Docker running icon in the system tray.

Docker running on Windows

Run Jenkins inside Container

To run Jenkins inside the container we need a Docker image that has Jenkins inside. Luckily we have official Jenkins images available on the Docker Hub. The image called jenkins/jenkins is the most up-to-date image you can get. This image with the tag lts is the stable and latest Jenkins version available as the Docker image.

https://hub.docker.com/r/jenkins/jenkins
jenkins/jenkins image on the Docker Hub

So let’s pull the image from the hub. You need to run the below command from the windows command prompt or the Powershell.

docker image pull jenkins/jenkins:lts

Based on the image size and the speed of the Internet, the pull operation may take a few seconds to a few minutes. If it’s successful, you should be able to see the downloaded image with the below command

PS C:\Users\Dinesh_Velhal> docker image lsREPOSITORY                                TAG                   IMAGE ID            CREATED             SIZE
jenkins/jenkins lts 256cb12e72d6 3 weeks ago 702MB

As you can see, the image size is 702MB and it was created 3 weeks ago. The tag lts means it's a Long Term Support version and is expected to be stable. Now we are all set to run the container using this image.

The command to run the container is as follows:

PS C:\Users\Dinesh_Velhal> docker container run -p 8080:8080 --name jenkins_lts jenkins/jenkins:lts

We will talk about the parameters in the command a little later in this article. For now, you can see that, after running this command, it starts generating logs on the console output (STDOUT) that shows the container has started and it’s starting the Jenkins server inside the container. In these logs, you’ll be able to see the Initial Admin Password for unlocking the Jenkins at the time of the first login.

*************************************************************
*************************************************************
*************************************************************
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
7caf0d794c094f6492925a0b87e86e36This may also be found at: /var/jenkins_home/secrets/initialAdminPassword*************************************************************
*************************************************************
*************************************************************

At this point, you can now open the URL http://localhost:8080 in the browser and see the Unlock Jenkins screen. This means the Jenkins server is successfully running inside the newly created container.

Jenkins Unlock screen

You can also check the status of the running container using below command:

PS E:\DOCKER\compose> docker container lsCONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                               NAMES
879369e658cf jenkins/jenkins:lts "/sbin/tini -- /usr/…" 17 minutes ago Up 17 minutes 0.0.0.0:8080->8080/tcp, 50000/tcp jenkins_lts

Congratulations! Now you have your first Jenkins setup inside the container running successfully. Of course, you need to complete the initial setup by unlocking the Jenkins followed by installing the commonly used plugins.

Let’s now discuss the parameters we passed while starting the container.

PS C:\Users\Dinesh_Velhal> docker container run -p 8080:8080 --name jenkins_lts jenkins/jenkins:lts
  • docker container run: This is the command used to start a container
  • -p 8080:8080: This image is configured to run the Jenkins on the port 8080 of the container instance. To actually access the Jenkins from the browser on your machine, you need to map the internal port of the Jenkins server to a real port on your machine. In this parameter, we inform docker to map 8080 port (the first 8080 in the parameter) on the local machine to the 8080 port from inside the container (the second 8080 in the parameter). This parameter allows us to access Jenkins from the local machine using the URL http://localhost:8080
  • --name jenkins_lts: we inform docker to name the container with the value given in the parameter - in this case jenkins_lts. If the--name parameter is not used, then Docker will generate a new unique name for the container.
  • jenkins/jenkins:lts: the name of the image just downloaded along with the Tag of the image.

Please note: You need to also expose the port 50000 if you want to use Build agents (slaves) through JNLP. For the sake of simplicity, this option is excluded here. you can easily enable it by using -p 50000:50000

There is a catch though!

If you stop and restart the same container, all your data created inside the container is lost. It means, most of the things you do in the Jenkins, E.g. pipelines created, modified configuration & settings, changed passwords, are all lost and you need to start all over again. So how to ensure that the objects and settings made inside the Jenkins in the container are persistent and survive the container restarts?

Fortunately, the solution is simple and elegant. In fact, there are two solutions:

1. Using Host Volumes

It involves mapping a host Operating System (Windows 10) folder as storage for Jenkins application. It can be specified at the time of Container creation with the option -v. Please see below the modified command:

PS C:\Users\Dinesh_Velhal> docker container run -v E:/docker_jenkins:/var/jenkins_home -p 8080:8080 --name jenkins_lts jenkins/jenkins:lts

In this case, using -v option, we are mapping a folder E:/docker_jenkins in Windows 10 to the Jenkins folder /var/jenkins_home. With this setting, when the container starts it uses the windows 10 folder as a storage for the container. This means, all your data persists even if you restart the container at any point!

This option is useful if you want to share the files between the host OS and the container. You need to be careful not to modify the contents of the folder manually or through some host OS process, else Jenkins may have issues in running.

2. Using Named Volumes

Docker supports creating named volumes that can be used by containers as persistent storage. Named volumes are completely managed by Docker, so there is no risk of host OS modifying the files in the volume accidentally. In general, named volumes are preferred due to the below reasons:

  • They make it possible to share data among multiple running containers
  • They allow you to store data locally or on remote hosts
  • They are easy to back up

Use below command to use named volume as persistent storage for Jenkins

PS C:\Users\Dinesh_Velhal> docker container run -v jenkins_volume:/var/jenkins_home -p 8080:8080 --name jenkins_lts jenkins/jenkins:lts

In this case, a new volume named jenkins_volume is created and then used as persistent storage by the Jenkins container. You can check the list of existing volumes using below command.

PS C:\Users\Dinesh_Velhal> docker volume lsDRIVER              VOLUME NAME
local jenkins_volume

To conclude

Docker opens up a lot of possibilities in how you host your applications and tools. The beauty of the Docker lies in the fact that it provides you an easy to understand interface to quickly start using the containers without understanding the complexity of how they actually run. You can see that using a set of easy-to-use commands you were able to host a Jenkins CI application on your machine in minutes.

For more details about the Jenkins docker image see this link.

I have kept this article easy and low on technical details, with the hope that it makes an easy starting point for the readers to learn and use Docker. They can then dive deep as they go ahead in learning it.

--

--