Docker-in-Docker OR Docker-outside-of-Docker ? Think Twice.

Daksh Jain
LinuxWorld Informatics Pvt. Ltd.
5 min readMay 15, 2020

--

If you run a docker container inside a container that already has docker installed, will the two of them run & be completely independent of each other?

Yes! This can be done, but this causes various problems, like the problem regarding the Linux Security Modules like AppArmor and SELinux.

So the question is do you really want Docker-in-Docker? Or do you just want to be able to run, build docker containers and push, pull images using your CI system, where this CI system itself is in a container?

If you are thinking for the latter then you are in the right place :)

You want a solution so that a CI system like Jenkins(on a container itself) can control docker containers.

Let’s first start by creating the Dockerfile. It is a good way to have all your files in 1 single directory called “Workspace”. So create a workspace and then name your file “Dockerfile”. You can also use a different name but by default Dockerfile is recommended.

The command from the above video:

# image name
FROM centos:7
# some basic softwares
RUN yum install sudo -y
RUN yum install net-tools -y
RUN yum install wget -y
# setup jenkins repository
RUN wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
RUN rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key# installing jenkins + java is required
RUN yum install jenkins -y
RUN yum install java-11-openjdk.x86_64 -y
# append in the sudoers file so that jenkins can get sudo powers
RUN echo "jenkins ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# some softwares to run docker from inside
RUN yum install ca-certificates -y
RUN yum install curl -y
RUN yum install gnupg2 -y
RUN yum install dnf -y
# setup repository for docker
RUN dnf install 'dnf-command(config-manager)' -y
RUN dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo -y
# install docker
RUN yum install docker-ce -y
RUN sudo usermod -a -G docker jenkins
# this is the most important command
CMD chmod 777 /var/run/docker.sock && java -jar /usr/lib/jenkins/jenkins.war

1. /var/run/docker.sock

This is the Unix socket to which the Docker daemon listens on by default, and it can be used to communicate with the daemon from within a container.

2. java -jar /usr/lib/jenkins/jenkins.war

This command is used to start the service of jenkins inside of that image which we are creating.

Now the main thing: CMD <cmd1> && <cmd2>, we are using the CMD command that would execute everytime the docker container starts. Sock daemon does not have enough permission to be able to run from jenkins user so to allow that we use chmod 777 command, so all the users can access it for now and with the latter command we finally start the jenkins service.

The command from the above video:

# docker build tag <name>:<version> <path of Dockerfile>
docker build -t docker_siblings:v1 /tryproj/Dockerfile

The image might take a while to get created for the first time so be patient with it :)

Now after the image is ready we can launch the container using this image.

The command from the above video:

docker run -it -p 8080:8080 -p 50000:50000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /jenkins_home:/var/jenkins_home \
--name jenkins_docker docker_siblings:v1

Now our Jenkins is up and running… Now login to your jenkins from a browser.

Then install Docker & Docker API plugin and restart your Jenkins.

Now there are 2 steps to do:

  1. First enable the cloud configuration in “Configure System” in “Manage Jenkins”.
Manage Jenkins -> Configure Jenkins -> Cloud

2. Now create a new job and in the build shell write this:

After this just save this job and build it !!

If you have followed all the steps then the job should run perfectly…

This output shows the container is created
docker exec -it jenkins_docker bash

Using this command we will get the bash shell of jenkins. Now here run the docker ps -a command to check whether the container is running or not…

Now how this work…

We have actually mounted the docker.sock file so that it can be used to communicate with the daemon from within a container.

So when we launch a container from within Jenkins it actually launches a sibling docker container which is accessible from the HOST as well as within the JENKINS CONTAINER.

Worked in collaboration with Ashish Kumar.

Connect me on my LinkedIn as well.

--

--

Daksh Jain
LinuxWorld Informatics Pvt. Ltd.

Automation Tech Enthusiast || Terraform Researcher || DevOps || MLOps ||