why docker daemon can't run when I build dind image

322 Views Asked by At

I want to make a preloaded dind image(named new-dind), so when CI use new-dind to do some test, it does not need to download the image.

this is my plan

  • write a scripts to pull image
  • use this scripts as an entrypoint

this is my scripts

#!/bin/bash
set -x
dockerd &
sleep 30
docker pull alpine:3.18

this is my Dockerfile

FROM docker:24.0.2-dind-alpine3.18

WORKDIR /app

RUN apk update && apk add --no-cache bash curl git

COPY daemon.json /etc/docker/daemon.json
COPY download.sh /app

RUN chmod +x download.sh
CMD ["/app/download.sh"]

when I use this command to build and run

docker build -t new-dind:t1 -f Dockerfile .
docker run --name new-dind --privileged new-dind:t1

it shows

+ dockerd
......
time="2023-10-08T09:45:42.958761499Z" level=info msg="Docker daemon" commit=659604f graphdriver=overlay2 version=24.0.2
time="2023-10-08T09:45:42.959336409Z" level=info msg="Daemon has completed initialization"
time="2023-10-08T09:45:43.004408329Z" level=info msg="API listen on /var/run/docker.sock"
+ docker pull alpine:3.18
error during connect: Post "http://docker:2375/v1.24/images/create?fromImage=alpine&tag=3.18": dial tcp: lookup docker on 10.0.1.254:53: no such host

it seems like docker daemon not run, what can I do?

when I move 'dockerd & ' to Dockerfile, it can not work too

1

There are 1 best solutions below

0
David Maze On

You can't create the image you're describing. If you look at the Docker Hub docker image page and click through to the docker:dind Dockerfile, you find this line

VOLUME /var/lib/docker

One of the consequences of the VOLUME directive is that an image can't change the contents in /var/lib/docker at all: it will get reset after each RUN instruction. Even emergency-use-only paths like docker commit can't create an image with content in this directory.


The script you show in principle could work, but it needs to run in a RUN line and not as the image's default CMD. If it's the CMD then it runs only when the container starts, which means that each invocation is pulling the image anew, which isn't your goal. Also since the script ends after doing the pull, at that point the container will exit.

However, Docker-in-Docker has some complex requirements, and it generally needs to run as --privileged. You can't run either an individual RUN line or the docker build as a whole as privileged; there simply isn't an option for it.

At a very mechanical level, the error you're getting is because the default configuration of the docker image expects to talk to a DinD docker on a host named docker in the same Docker network. (The linked code tries to look for a Docker daemon in other places, but it runs before your dockerd invocation.) You would need to do something like unset DOCKER_HOST to return to the default, but then you'll hit the other problems previously described.