How do RUN docker in Dockerfile?

116 views Asked by At
FROM kindest/node:v1.25.3

RUN docker pull some-image:latest

If I call docker build on my MacOS machine, I get

failed to dial "/run/containerd/containerd.sock": context deadline exceeded: connection error: desc = "transport: error while dialing: dial unix:///run/containerd/containerd.sock: timeout"

Background: I am playing around with kind. If I start my kind cluster it needs to load a lot of images. I would like to shorten that by using a custom node image, which already has all docker images pre-loaded.

I also tried

FROM kindest/node:v1.25.3

COPY 4188262a351f156e8027ff81693d771c35b34b668cbd61e59c4a4490dd5c08f3.tar /4188262a351f156e8027ff81693d771c35b34b668cbd61e59c4a4490dd5c08f3.tar
RUN tar -xvf /4188262a351f156e8027ff81693d771c35b34b668cbd61e59c4a4490dd5c08f3.tar -C /var/lib/containerd/io.containerd.content.v1.content/blobs/sha256
RUN rm /4188262a351f156e8027ff81693d771c35b34b668cbd61e59c4a4490dd5c08f3.tar 

but this does not seem to load the image properly

1

There are 1 answers

4
David Maze On

You usually can't RUN docker at all. One of the big reasons, as noted in a comment, is that whatever the main container process normally is isn't running in the Dockerfile; there isn't a Docker daemon you can talk to.

However, the kind Node image documentation notes

/kind/images/ contains various *.tar files which are Docker image archives, these images will be loaded by the cluster tooling prior to running kubeadm

So if you can pick out the Docker images you're going to use

sed -ne 's/^ *image: *//p' *-deployment.yaml

then you can individually save each of those images

for image in ...; do
  docker pull "$image"
  docker save -o "$image.tar" "$image"
done

and then include those in your custom node image

FROM kindest/node:v1.25.3
COPY *.tar /kind/images/

Often for this kind of setup, there's a pattern of putting the content needed for the initialization somewhere a first-time startup script can find it. This is similar to database images, for example: you don't directly run SQL commands in a Dockerfile but instead put an initialization script in /docker-entrypoint-initdb.d. This is a similar pattern where you can't pull the images in the Dockerfile but you can at least put the content in the image, and they won't need to be (re-)fetched over the network.

(Even if you're just saving an image to a file, you can't do this via docker commands in a Dockerfile. I believe there are other commands that can do this that don't require connecting to a Docker daemon, but I can't recommend any of those in particular.)