Jenkins is a free and open source automation server, which is used to automate software building, testing, deployment, etc.
wanted to have a quick and easy way to run Jenkins inside docker, but
also use docker containers to run jobs on the dockerized Jenkins. Using
docker for jobs makes it easy to encode job runtime dependencies in the
source code repo itself.
The official document on running Jenkins in docker is pretty comprehensive. But, I wanted a version using docker-compose (on Linux).
So, I started with a basic compose file:
When using this ( docker-compose up -d ), things came up properly, but Jenkins did not have access to the docker daemon running on the host. Also, the docker cli binary is not present inside the container.
The way to achieve this was to mount the docker socket and cli binary to inside the container so that it can be accessed. So, we come to the following compose file:
But, when trying to run docker ps inside the container with the above compose file, I was still getting the error: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock. This is because the Jenkins container is running with the jenkins user, which does not have access to use that socket.
From my research, the commonly recommended ways to solve this problem were:
Run the container as root user
chmod the socket file to 777
Install sudo inside the container and give the jenkins user access to sudo without needing to enter password.
A more secure way is to create the docker group inside the container, and add the jenkins user to that group. But, this requires us to build a custom image.
Also, the group id of the docker
group inside and outside the container have to be the same, so I had to
add an extra check which deletes any existing group inside the
container which uses the same group id, then creates the new docker group with the passed group id, and then adds the jenkins user to the docker group.
So, the final Dockerfile is:
And the final docker-compose.yml file is:
The docker_group_id argument can be edited in the compose file. Command to get the group id of docker:
With the above, everything works:
Here is an excellent guide
on how to setup Jenkins configuration as code. This will make this
setup even better because nothing will need to be configured inside
Jenkins manually - it will all be driven by code / files.