0

Currently I have the following Dockerfile:

FROM debian:10 as builder
RUN sleep 10
COPY input input
# worlds most trivial build pipeline
RUN cat input > artifact

FROM debian:10
COPY --from=builder artifact artifact
RUN cat artifact
COPY input2 input2

And I have docker-compose file like the following:

%YAML 1.1
---
version: '3.7'
services:
  sdn-controller:
    build:
      context: .
      cache_from:
      - hansbogert/test1:latest
      args:
      - BUILDKIT_INLINE_CACHE=1
    image: hansbogert/test1:latest

And two empty files:

$ touch input input2

If I do an initial build with buildkit, and push them to the registry:

export DOCKER_BUILDKIT=1 
docker-compose build 
docker-compose push

Keeping the cache-from in mind in the compose file:

case 1) I expect that when I have no local cache, i.e.,

docker rmi hansbogert/test1 ; docker image prune -f; docker builder prune -af

that a new build would be completely cached, (which it is):

docker-compose build 

[trunc'd, but all cached]

case 2) I expect that if I edit the input2 file, that only the latest stage in the docker file, starting from the COPY-ing of input2 needs to be redone, which it does:

$ echo 1 > input2
$ docker rmi hansbogert/test1 ; docker image prune -f; docker builder prune -af
$ docker-compose build 
[trunc'd]
=> CACHED [stage-1 3/4] RUN cat artifact                                                                                            0.7s
 => => pulling sha256:f33c84f9d3c6505acdda2a6d1c7238c853e07f3723e4a5d4c9eb65a163710ffd                                               0.3s
 => => pulling sha256:0b00a0a96175fa32a06c3741ac1fb655aafc2ed1584eebfd2e213561998f7bea                                               0.4s
 => [stage-1 4/4] COPY input2 input2                                                                                                 0.0s
 => exporting to image                                                                                                           
...

case 3) When I edit the input file, I expect the first stage to be cached up till the COPY input input line, alas, that's what does not happen, signalled by the uncache RUN sleep 10 line:

$ echo 1 > input
$ docker rmi hansbogert/test1 ; docker image prune -f; docker builder prune -af
$ docker-compose build 

=> [internal] load build definition from Dockerfile                                                                                 0.0s
 => => transferring dockerfile: 254B                                                                                                 0.0s
 => [internal] load .dockerignore                                                                                                    0.1s
 => => transferring context: 2B                                                                                                      0.0s
 => [internal] load metadata for docker.io/library/debian:10                                                                         0.0s
 => importing cache manifest from hansbogert/test1:latest                                                                            1.3s
 => [builder 1/4] FROM docker.io/library/debian:10                                                                                   0.1s
 => [internal] load build context                                                                                                    0.0s
 => => transferring context: 71B                                                                                                     0.0s
 => [builder 2/4] RUN sleep 10                                                                                                      10.5s
 => [builder 3/4] COPY input input                                                                                                   0.1s
 => [builder 4/4] RUN echo input > artifact                                                                                          0.6s
 => CACHED [stage-1 2/4] COPY --from=builder artifact artifact                                                                       0.0s
[trunc'd, but note  that this stage is cached as much as possible! ]

Main question: Is there a way to get caching for stages other than the stage in the final image?

There seems to be a relevant issue on github

However, in its conclusion it does not seem to address my above problem.

hbogert
  • 4,198
  • 5
  • 24
  • 38
  • When you remove your images, did the Debian base image update from what you may have pulled before? – BMitch Oct 25 '21 at 22:01
  • No, I get what you mean, but definitely not, I can reproduce this in a time interval of seconds, time and time again. – hbogert Oct 26 '21 at 07:52

1 Answers1

0

Currently this is not possible without using buidlx or 'pure' buildkit. Inline cache, which is what you are using in buildkit terminology, is not able to give you cache for all stages, as indicated by the following paragraph from buildctl's README:

In most case you want to use the inline cache exporter. However, note that the inline cache exporter only supports min cache mode. To enable max cache mode, push the image and the cache separately by using registry cache exporter.

Ergo, you need buildkit's cache-to="type=registry,mode=max".

hbogert
  • 4,198
  • 5
  • 24
  • 38