Giving Jenkins access to Docker

In order to be able to build and run Docker containers within a Jenkins BlueOcean pipeline, you need access to a Docker installation - you can either install Docker within the Jenkins container, the so called "Docker in Docker" method, or you can give it access to the Docker setup that Jenkins itself is running under, to create so called "sibling" containers.

I will be doing the latter.

The first thing to do is to create the Jenkins container with the right volumes mounted:

docker run \  
    -d \
    --restart=always \
    --name jenkins \
    -p 80:8080 \
    -p 50000:50000 \
    -v /storage/jenkins/:/var/jenkins_home \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v $(which docker):/usr/bin/docker \
    jenkins:2.32.3

Lets break that down a little:

  • -d - detach this container, don't run it interactively
  • --restart=always - always attempt a restart of this container
  • --name jenkins - give it a useful name
  • -v /storage/jenkins/:/var/jenkins_home - give it a volume for persistent storage of data, I'm using a local directory
  • -v /var/run/docker.sock:/var/run/docker.sock - give it access to the hosts Docker socket, so it can talk to the Docker engine on the host
  • -v -v $(which docker):/usr/bin/docker - give it access to the hosts Docker commands (you could alternatively add these to the Jenkins image)
  • jenkins:2.32.3 - use the official Jenkins image, version 2.32.3

Once Jenkins is up and running, we need to ensure that the Jenkins user can access the Docker commands - Docker requires a user to either be at root level (via sudo) or a member of the docker group.

So lets add a docker group.

Run the following command to give yourself a root level shell within the Jenkins container we just created:

docker exec -it --user root jenkins /bin/bash  

Within that shell, run the following commands:

groupadd -g 999 docker  

This adds the docker group with the right group ID - Docker uses the id of 999, and this is the ID that is set on the docker.sock so we need to honour this.

usermod -aG docker jenkins  

This adds the jenkins user to the right group.

Exit the root shell, we don't need it any more.

Now give yourself a normal user shell within the Jenkins container:

docker exec -it jenkins /bin/bash  

We can now test that we can talk to the Docker engine, simply by asking it to list all the containers running:

jenkins@40115497843c:/$ docker ps  
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                            NAMES  
40115497843c        jenkins             "/bin/tini -- /usr..."   24 minutes ago      Up 24 minutes       0.0.0.0:50000->50000/tcp, 0.0.0.0:80->8080/tcp   jenkins  

Even though we are within the Jenkins container, its listing itself as running - this is because we are actually talking to the Docker engine that that container runs on.

Neat, eh?