Search code examples
cachingdockerdocker-registry

How to setup docker to use cache from registry on every build step


I have two servers with docker and one server with my private registry.

I built Dockerfile on the first machine; then I pushed the image to the registry.

Is it possible to build Dockerfile on the second machine immediately using cache from my registry? If no, is there any way to speed up building "almost" same Dockerfiles without writing my own cache?

It tried to setup --registry-mirror but it didn't help.


Solution

  • for docker > 1.10, I found something on this issue: https://github.com/docker/docker/issues/20316#issuecomment-221289631

    Given this Dockerfile

    FROM busybox
    RUN mkdir this-is-a-test
    RUN echo "hello world"
    

    run docker build -t caching-test .

    Then we can see the layers comprising the image with docker history caching-test

    3e4a484f0e67        About an hour ago   /bin/sh -c echo "Hello world!"                  0 B                 
    6258cdec0c4b        About an hour ago   /bin/sh -c mkdir this-is-a-test                 0 B                 
    47bcc53f74dc        9 weeks ago         /bin/sh -c #(nop) CMD ["sh"]                    0 B                 
    <missing>           9 weeks ago         /bin/sh -c #(nop) ADD file:47ca6e777c36a4cfff   1.113 MB  
    

    The change to save/load in 1.11 preserves the relationship between parent and child layers, but only when they are saved via docker save together. We can see the parent of the final test image by running docker inspect test | grep Parent.

    $ docker inspect caching-test | grep Parent
    "Parent": "sha256:6258cdec0c4bef5e5627f301b541555883e6c4b385d0798a7763cb191168ce09", 
    

    This is the second-to-top layer from our Docker history output.

    In order to recreate the cache using save and load, you need to save out all of the images and layers that are referenced as parents. In practice this typically means that you need to save each layer, as well as the FROM image, in the same command.

    docker save caching-test 6258cdec0c4b busybox > caching-test.tar -- note that we can also give the layer names instead of IDs to the save command.

    Let's purge everything and then reload the image from the tar file. docker rmi $(docker images -q). Confirm that no images exist.

    Then run docker load -i caching-test.tar. If you look at the images, you'll see busybox, and then caching-test. Running docker history caching-test will show you the exact same output as when the image was initially built. This is because the parent/child relationships were preserved via save and load. You can even run docker inspect caching-test | grep Parent and see the exact same ID given as the parent layer.

    And running a rebuild of the same Dockerfile will show you that the cache is being used.

    Sending build context to Docker daemon 5.391 MB
    Step 1 : FROM busybox
     ---> 47bcc53f74dc
    Step 2 : RUN mkdir this-is-a-test
     ---> Using cache
     ---> 6258cdec0c4b
    Step 3 : RUN echo "hello world"
     ---> Using cache
     ---> 3e4a484f0e67
    Successfully built 3e4a484f0e67
    

    EDIT: Below this works only Before docker 1.10

    On the second machine you can docker pull theimagefromthefirstdockerfileontheregistry before building the new one.

    That way you are sure that every layer is present on the second machine.

    The docker-engine doesnt query the registry each time a layer is built (it doesn't even knows it), it would be too slow/heavy so I dont think there is another way.