docker/buildx

[feature request] Support for --squash

Niek opened this issue · 10 comments

Niek commented

The --squash option is not yet implemented in buildx:

buildx/commands/build.go

Lines 85 to 87 in 3dfbe2c

if in.squash {
return errors.Errorf("squash currently not implemented")
}

Are there any plans to add this soon?

No plans atm. Squash was never taken out of experimental and is only supported in moby outside the builder component. You should squash layers with a multi-stage dockerfile(if you are sure you know what you are doing and need to squash at all).

I would vote for having squash in buildx, that is very convenient and reduces drastically the size of a an image.

I'd also like to voice support for this issue. Even with multi-stage builds you still wind up with multiple layers that could be squashed into one. No need to download an untar a bunch of small files when one would do. Honestly, I'm hard pressed to think of an instance where a single layer and the end would not be preferred, assuming caching still works the same with squash.

If you have the ubuntu docker image pulled, and then you created a squashed image extended from ubuntu, when you try to pull it, it will pull it from scratch instead of reusing the existing Ubuntu image you have as a cached layer.

assuming caching still works the same with squash.

It does not work the same. Caching happens per layer, so you can't get any matches for squashed image.

Download would only be slower if you run something like RUN rm .. as part of your Dockerfile, again something that you should not do at all if you use multi-stage builds.

Even with mode=max?

I had been using --squash to reduce the size of the final image, and managed to get the equivalent reductions without it thanks to this answer on SO.

The idea is to add a final stage which copies in everything from the image:

FROM scratch as release
COPY --from=release-build / /
ENTRYPOINT ["/entrypoint.sh"]

Hm... interesting, but I think this will probably wipe out all environment variables and labels as well, right?

Hm... interesting, but I think this will probably wipe out all environment variables and labels as well, right?

Right. Can we just have squash for those people that really want to use it? I just want one layer at the end. For cases where you have one or two binaries, maybe some ENVs and bunch of LABELs. I'd rather not have to do yet another FROM scratch and COPY --from=previous / / It is faster because you're not waiting for multiple tiny layers to extract. It should be able to cache all of the intermediate layers, with --cache-to mode=max. Yes the final image is not cacheable, but if we're going from scratch anyway does it matter?

Even with mode=max?

--squash (the one still in dockerd) does not cache anything. If you use multi-stage builds then mode=max works but mode=max only works with a completely separate target where now all your layers (including the ones where you ran rm .. if you use the full / squash) are now pushed. For the regular inline cache that is based on the image itself(and does not make your build slower), you can't get any cache because there are no layers in the image.