Exporting intermediate layers on build failure
For ephemeral buildkit instances where a local, shared disk cache isn't necessarily feasible, it seems like it'd be helpful to export the external build cache for all completed steps even if the entire build itself has failed.
This is a somewhat minimal reproduction of the use-case:
$ cat Dockerfile
FROM alpine
RUN cat /dev/urandom | head -c 100 | sha256sum > unique
RUN exit 1
$ buildkitd &
$ buildctl b --export-cache type=registry,mode=max,ref=mycache-1 --import-cache type=registry,ref=mycache-1 --frontend dockerfile.v0 --local context=. --local dockerfile=.
$ kill %1
$ rm -rf /var/lib/buildkit/
$ buildkitd &
$ buildctl b --export-cache type=registry,mode=max,ref=mycache-1 --import-cache type=registry,ref=mycache-1 --frontend dockerfile.v0 --local context=. --local dockerfile=.
I can imagine a scenario where it's useful to ensure the first run step (cat /dev/urandom being a proxy for something "expensive") is cached no matter if the last step fails. For example, when iterating on a new image.
I made an attempt at adding a feature for this in #1931, but I guessed an issue might spur some conversation about whether this is a worthwhile feature. I could definitely buy that it's a niche case and not necessarily broadly applicable to the current caching paradigm.
Presently trying to figure out why a build step isn't working, I use to just grab the digest/image-hash value and use docker run <digest> bash to examine it, but with BuildKit this seems impossible since the cache isn't shared with Docker. Really need a way to diagnose intermediate build steps. Still researching but came across this which seems like a necessary component to doing so.