Running Docker in Docker sounds like a strange thing to do, however it’s very useful when you’re running a tool such as Jenkins where you need to build and manage containers within your pipelines.
This solution doens’t run docker within docker, but rather passes the control socket (/var/run/docker.sock
) into a container. This allows the docker tools within the container to talk to the docker process outside of the container.
I came across this issue while following along with Richardo Andre’s excellent course “Jenkins, From Zero to Hero” on Udemy. However the solution presented there was an example and didn’t feel right from a security point of view. The issue is that the socket needs to be read/write to the Jenkins user within the jenkins container.
If you just mount the socket file in and don’t do anything to fix the permissions issue, the error you’ll get is: “Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/json: dial unix /var/run/docker.sock: connect: permission denied
“
To solve this, the GID for the socket and the docker group both inside and outside the container all need to match. Notice below where ‘133’ is the group ID outside the container of the docker group. You might want to alter this to be an argument you can pass in, or dynamically generate it with something like “stat -c '%g' /var/run/docker.sock
“
FROM jenkins/jenkins USER root RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ python get-pip.py && \ pip install ansible RUN apt-get update && \ apt-get -y install apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common && \ curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \ add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/debian \ $(lsb_release -cs) \ stable" && \ apt-get update && \ apt-get -y install docker-ce docker-ce-cli containerd.io && \ curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \ chmod +x /usr/local/bin/docker-compose RUN groupmod -g 133 docker && \ usermod -aG docker jenkins USER jenkins
The docker-compose.yaml looks like this, mounting the socket file into the container
services: jenkins: container_name: jenkins image: jenkins/docker build: context: pipeline ports: - "8080:8080" volumes: - "/my/path/jenkins-data/jenkins_home:/var/jenkins_home" - "/var/run/docker.sock:/var/run/docker.sock" networks: - net