docker in docker jenkins

Jenkins is a great Open Source CI/CD platform, with full Docker build agent support.

Of course, we want to run our Jenkins inside of a Docker container.

By default, you cannot run "Docker in Docker" containers within the jenkins/jenkins:lts Docker image.

This is both because the image does not have the docker binary installed, and because it does not have access to the docker socket.

To run Docker in Docker Jenkins, we must first create a custom Dockerfile to add docker and docker-compose.

Dockerfile
FROM jenkins/jenkins:lts

USER root

RUN curl -fsSLO https://get.docker.com/builds/Linux/x86_64/docker-17.04.0-ce.tgz \
  && tar xzvf docker-17.04.0-ce.tgz \
  && mv docker/docker /usr/local/bin \
  && rm -r docker docker-17.04.0-ce.tgz \
  && curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` \
    -o /usr/local/bin/docker-compose \
  && chmod +x /usr/local/bin/docker-compose

USER jenkins


While the image created from the above Dockerfile will have docker installed, it will still be unable to run Docker in Docker builds.

This is because by default, it will not be connected to the Docker socket on the host machine. This is a security measure to ensure that containers are properly sandboxed.

Allowing the container to access the host Docker daemon is effectively giving the container the power to control all containers on the host (or swarm!) - including itself.

For this reason, this should be run in a dedicated, sandboxed environment - as your build / deployment environment should be already!

Run Command
docker run -d -p 8080:8080 \
       -p 5000:5000 \
       -v jenkins:/var/jenkins_home \
       -v /var/run/docker.sock:/var/run/docker.sock \
       --restart always \
       --name jenkinsdock \
       --group-add 1000 --group-add 999 \
      jenkinsdock


This command binds to the Jenkins default ports and creates a named volume jenkins to store the Jenkins data - same as usual.

The second volume mount enables the container to launch and manage containers on the host.

We must also add the executing user jenkins to the requisite groups to execute docker commands.

Launching

Use the run command above, or use docker-compose to craft a more reader-friendly yaml configuration.

Once launched, check the logs for the temporary Jenkins administrator password.

You can then log in and set up your Jenkins server as usual. It will now be able to execute docker and docker-compose builds, while itself is running in a container.

code

last updated 2024-03-18