8

I am running a docker-in-docker container that always uses the same few images. I would like to pre-pull those in my dind container so I don't have to pull them at startup. How would I be able to achieve this?

I was thinking of building my own dind image along the lines of

FROM docker:18.06.1-ce-dind

RUN apk update && \
    apk upgrade && \
    apk add bash

RUN docker pull pre-pulled-image:1.0.0

Obviously above Dockerfile will not build because docker is not running during the build, but it should give an idea of what I'd like to achieve.

David Maze
  • 130,717
  • 29
  • 175
  • 215
Maarten Dhondt
  • 577
  • 1
  • 9
  • 22

2 Answers2

7

You can't do this.

If you look at the docker:dind Dockerfile it contains a declaration

VOLUME /var/lib/docker

That makes it impossible to create a derived image with any different content in that directory tree. (This is the same reason you can't create a mysql or postgresql image with prepopulated data.)

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • 1
    Hi @David , could you please explain why commiting the container like in my answer will not work – LinPy Nov 07 '19 at 13:40
  • 2
    When you launch the DinD container, the host Docker will mount an anonymous volume over the container Docker's `/var/lib/docker` tree. If you `docker pull` an image in the inner Docker, the content will get put in the host Docker's anonymous volume and not in the inner Docker's container filesystem. `docker commit` doesn't consider volumes at all, so you'll get an unchanged image with nothing preloaded in it. – David Maze Nov 07 '19 at 13:42
7

Here is some way to achieve this.

The idea is to save images that you want to use, and then to import this images during the container startup process.

For example, you can use a folder images where to store your images.

And you have to use a customized entrypoint script that will import the images.

So the Dockerfile will be :

FROM docker:19.03-dind

RUN apk add --update --no-cache bash tini

COPY ./images /images
COPY ./entrypoint.sh /entrypoint.sh

ENTRYPOINT ["tini", "--", "/entrypoint.sh"]

(tini is necessary to load images in background)

And the entrypoint.sh script :

#!/bin/bash

# Turn on bash's job control
set -m

# Start docker service in background
/usr/local/bin/dockerd-entrypoint.sh &

# Wait that the docker service is up
while ! docker info; do
  echo "Waiting docker..."
  sleep 3
done

# Import pre-installed images
for file in /images/*.tar; do
  docker load <$file
done

# Bring docker service back to foreground
fg %1

FYI, an example on how to save an image :

docker pull instrumentisto/nmap
docker save instrumentisto/nmap >images/nmap.tar
coredump
  • 594
  • 5
  • 8