70

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:

  • what is the difference between the docker:dind and the docker:latest images?
  • (most importantly): why are both the service and the docker image needed (e.g. as indicated in this example, linked to from the github documentation) to perform e.g. a 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

Community
  • 1
  • 1
pkaramol
  • 9,548
  • 14
  • 80
  • 167

2 Answers2

75

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.

davidlj95
  • 66
  • 5
saraedum
  • 974
  • 9
  • 6
  • 1
    To add to @saraedum 's post, if I am not mistaken, if you specify the `DOCKER_HOST` var to be what the service expects which I think is `DOCKER_HOST: "tcp://${DOCKER_REGISTRY}__library__docker:2375"` (and you do __not__ mount it to the host's socket), this will __disable__ docker layer caching (just a sidenote on the actual differences on using vs not using the service) – pkaramol Nov 13 '18 at 15:42
  • 2
    Thank you for the great explanation! A follow-up question, if the only difference is `docker:dind` has started docker daemon as entrypoint, why can't we use `docker:dind` directly as image? Is it because in the `docker:dind`, it is also configured to connect to `tcp://docker:2375` insteand of `tcp://localhost:2375`? – xiGUAwanOU Jul 24 '19 at 10:05
-6

The container will contain only things defined in a docker image. You know you can install anything, starting from a base image. But you can also install Docker (deamon and client) in a container, that is to say a Docker IN Docker (dind). So the container will be able to run other containers. That's why gitlab need this.

Fiber Optic
  • 130
  • 5
  • 1
    Yes, but how does the dind container have anything to do with the docker:latest container? Does it run inside of it? The only explanation from gitlab is that services can be used to spin up and link in auxiliary containers like a db for instance. I’m not seeing how just having a dind container available and linked would change anything. – Matt Nov 27 '17 at 21:51
  • Yes docker is installed in the dind image. What is your problem exactly? – Fiber Optic Nov 27 '17 at 21:56