According to the official gitlab documentation, one way to enable docker build
within ci
pipelines, is to make use of the dind
service (in terms of gitlab-ci
services).
However, as it is always the case with ci jobs running on docker executors, the docker:latest
image is also needed.
Could someone explain:
docker:dind
and the docker:latest
images?docker build
whithin a ci job? doesn't the docker:latest
image (within which the job will be executed!) incorporate the docker daemon (and I think the docker-compose
also), which are the tools necessary for the commands we need (e.g. docker build
, docker push
etc)?Unless I am wrong, the question more or less becomes:
Why a docker client and a docker daemon cannot reside in the same docker (enabled) container
Introduction. Docker in Docker (also known as dind) is, as the name implies, running Docker on top of a Docker container. Controlling containers from a Docker container is not a particular use case but is often necessary to run CI tools such as Jenkins on top of a Docker container.
GitLab Runner can use Docker to run jobs on user provided images. This is possible with the use of Docker executor. The Docker executor when used with GitLab CI, connects to Docker Engine and runs each build in a separate and isolated container using the predefined image that is set up in .
GitLab CI in conjunction with GitLab Runner can use Docker Engine to test and build any application. Docker is an open-source project that allows you to use predefined images to run applications in independent "containers" that are run within a single Linux instance.
what is the difference between the docker:dind and the docker:latest images?
docker:latest
contains everything necessary to connect to a docker daemon, i.e., to run docker build
, docker run
and such. It also contains the docker daemon but it's not started as its entrypoint.docker:dind
builds on docker:latest
and starts a docker daemon as its entrypoint.So, their content is almost the same but through their entrypoints one is configured to connect to tcp://docker:2375
as a client while the other is meant to be used for a daemon.
why are both the service and the docker image needed […]?
You don't need both. You can just use either of the two, start dockerd
as a first step, and then run your docker build
and docker run
commands as usual like I did here; apparently this was the original approach in gitlab at some point. But I find it cleaner to just write service: docker:dind
instead of having a before_script
to setup dockerd
. Also you don't have to figure out how to start & install dockerd
properly in your base image (if you are not using docker:latest
.)
Declaring the service in your .gitlab-ci.yml
also lets you swap out the docker-in-docker easily if you know that your runner is mounting its /var/run/docker.sock
into your image. You can set the protected variable DOCKER_HOST
to unix:///var/run/docker.sock
to get faster builds. Others who don't have access to such a runner can still fork your repository and fallback to the dind
service without modifying your .gitlab-ci.yml
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With