moby / buildkit

concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit
https://github.com/moby/moby/issues/34227
Apache License 2.0
8.03k stars 1.12k forks source link

Stages in multi-stage dockerfile not cached with DOCKER_BUILDKIT=1 #1930

Open umarcor opened 3 years ago

umarcor commented 3 years ago

The following two stages of the same Dockerfile:

https://github.com/hdl/containers/blob/67486e6ca9d75e210bea164c4bfdbeff8c3f11c1/nextpnr.dockerfile#L40-L46

are built:

https://github.com/hdl/containers/blob/67486e6ca9d75e210bea164c4bfdbeff8c3f11c1/.github/bin/dockerBuild#L13-L17

one after the other:

https://github.com/hdl/containers/blob/67486e6ca9d75e210bea164c4bfdbeff8c3f11c1/.github/workflows/nextpnr.yml#L32-L33

in a GitHub Actions workflow with DOCKER_BUILDKIT set:

https://github.com/hdl/containers/blob/67486e6ca9d75e210bea164c4bfdbeff8c3f11c1/.github/workflows/nextpnr.yml#L12

Both images are built from scratch. See https://github.com/hdl/containers/runs/1642109588?check_suite_focus=true. I would expect the second build to last a few seconds, because it is just copying some additional files. Actually, there are other two stages in the same dockerfile, which are built afterwards: https://github.com/hdl/containers/blob/67486e6ca9d75e210bea164c4bfdbeff8c3f11c1/nextpnr.dockerfile#L67-L73. In that case, the behaviour is as expected and building the second stage takes 3-5 seconds.

Why does hdlc/nextpnr:icestorm not reuse the cache from hdlc/nextpnr:ice40, but hdlc/nextpnr:prjtrellis reuses the one from hdlc/nextpnr:ecp5?

tonistiigi commented 3 years ago

The dev image used in these subsequent builds is not the same image:

#7 [build 1/2] FROM docker.io/hdlc/build:dev@sha256:6bf17d2932627dc3270bc15...
#7 resolve docker.io/hdlc/build:dev@sha256:6bf17d2932627dc3270bc15ad7193d4681b3406d76c4ad91eef66288bfbcb25b done
#7 sha256:6bf17d2932627dc3270bc15ad7193d4681b3406d76c4ad91eef66288bfbcb25b 1.17kB / 1.17kB done
#7 sha256:40cd13ec5c15e93291e87bff1731e796041441d528129519046e082c32a9f710 3.04kB / 3.04kB done

#7 [build 1/2] FROM docker.io/hdlc/build:dev@sha256:c3d8214e245245b97f04635...
#7 resolve docker.io/hdlc/build:dev@sha256:c3d8214e245245b97f046353f28b53f534155f351b7c74d117738346a1f2fa03 done
#7 sha256:c3d8214e245245b97f046353f28b53f534155f351b7c74d117738346a1f2fa03 1.17kB / 1.17kB done
#7 sha256:5f06e76ae3ba3ead917404bdf935841d8202d263131fe99680b190de374b50de 3.04kB / 3.04kB done

So either it got updated or a different image was requested.

umarcor commented 3 years ago

Interesting... there is a race condition between workflows indeed. hdlc/build:dev is updated by another workflow, between the first and the second build.

Is it possible to prevent build from retrieving the latest image? I'd like to pull them once (either manually or in the first build) and let other subsequent builds use the images that are already available locally. That is, I want all the images built in a single workflow to share the same base images.