The simple way to run Docker-in-Docker for CI

Every now and then I come across the requirement to build Docker images inside a Docker container. More often than not, this happens when I need to build Docker images as part of a Continuous Integration pipeline running Jenkins - where the Jenkins master (or agent) is running inside a Docker container.

 

Docker doesn't recommend running the Docker daemon inside a container (except for very few use cases like developing Docker itself), and the solutions to make this happen are generally hacky and/or unreliable.

 

Fear not though, there is an easy workaround: mount the host machine's Docker socket in the container. This will allow your container to use the host machine's Docker daemon to run containers and build images.

 

Your container still needs compatible Docker client binaries in it, but I have found this to be acceptable for all my use cases.

 

The TL;DR version using my prebuilt image is:

docker run \
  -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --name jenkins \
  getintodevops/jenkins-withdocker:lts

The guide below is for Jenkins, but you can apply the same logic to any other build server.

 

Building Docker containers with Jenkins inside a container

First, we'll run Jenkins as a container using the official Jenkins image:

docker run -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --name jenkins \
  jenkins/jenkins:lts

Note that the key here is mounting /var/run/docker.sock from the host machine to the same location inside the container.

 

Then, we'll need to install the Docker binaries inside the container. Spawn an interactive shell inside the running Jenkins container:

docker exec -it -u root jenkins bash

Because the official Jenkins image is based on Debian 9, we can use apt to install the Docker binaries as instructed in the Docker installation guide. This is a single snippet to install some prerequisites, configure the official Docker apt repositories and install the latest Docker CE binaries:

apt-get update && \
apt-get -y install apt-transport-https \
     ca-certificates \
     curl \
     gnupg2 \
     software-properties-common && \
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
   $(lsb_release -cs) \
   stable" && \
apt-get update && \
apt-get -y install docker-ce

Caveat: The Docker daemon running on your host machine must be compatible with the version of client binaries you are installing. To verify the version, run docker version on your host machine.

 

Ta-da! Your Jenkins container should now have a functioning Docker installation. Verify by running:

docker ps

The output should be the same as when running the command on the host machine (you should at least expect to see the Jenkins container running!).

 

Next, you'll need to finish the installation of Jenkins as usual. Open the Jenkins installer by navigating to http://localhost:8080.

 

You will need the initial admin password, which can be obtained by running:

 

docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

Next select "Install recommended plugins", and wait for Jenkins to install everything. The Docker Pipeline plugin is installed by default, which means you are ready to go!

 

I have pre-built a Jenkins 2.73.1 image with Docker 17.09.0-ce binaries. It's available on Docker Hub as getintodevops/jenkins-withdocker.

 

Next, read How to build your first Docker image with Jenkins!

 

tip, docker

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值