Docker in Docker

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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.