Skip to content

[builder-next] fix squashing base image layer#39187

Draft
Blyschak wants to merge 2 commits intomoby:masterfrom
Blyschak:builder-next-squash
Draft

[builder-next] fix squashing base image layer#39187
Blyschak wants to merge 2 commits intomoby:masterfrom
Blyschak:builder-next-squash

Conversation

@Blyschak
Copy link

@Blyschak Blyschak commented May 8, 2019

Signed-off-by: Stepan Blyshchak stepanblischak@gmail.com

Fixes #38903

- What I did
I am trying to fix "--squash" using DOCKER_BUILDKIT=1 squashes the top layers and the base image always resulting in one layer. Legacy builder behavior is to not squash the base layer.
This is quite important because multiple images that were squashed cannot share the same base image affecting the disk space (especially when dockers run on device which has a small drive)

- How I did it
Export base image config from Dockerfile2LLB, so later can pass to SquashImage.
Here I changed the input of SquashImage from base ID string to Image object, since when base image is resolved remotely it is not present in ImageStore, which is yet another behavior change comparing to legacy builder:

root@8be8a791847f:~/test# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
root@8be8a791847f:~/test# DOCKER_BUILDKIT=1 docker build --squash -t busybox-squashed -f- . <<EOF
FROM busybox
COPY ./one /one
COPY ./two /two
COPY ./three /three
EOF

[+] Building 3.3s (9/9) FINISHED                                                                                                                                                                                    
...
root@8be8a791847f:~/test# docker images # there is no busybox:latest pulled
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox-squashed    latest              e5ef8abf1e26        4 seconds ago       1.2MB
<none>              <none>              cc706b1284cd        19 minutes ago      1.2MB

TODO: maybe it is better to pull base image from remote in exporter and so SquashImage will work as it is right now?

- How to verify it

  1. squash with buildkit
root@8be8a791847f:~/test# DOCKER_BUILDKIT=1 docker build --squash -t busybox-squashed -f- . <<EOF
FROM busybox
COPY ./one /one
COPY ./two /two
COPY ./three /three
EOF
[+] Building 2.8s (9/9) FINISHED                                                                                                                                                                                    
 => [internal] load build definition from Dockerfile                                                                                                                                                           0.6s
 => => transferring dockerfile: 102B                                                                                                                                                                           0.0s
 => [internal] load .dockerignore                                                                                                                                                                              0.4s
 => => transferring context: 2B                                                                                                                                                                                0.0s
 => [internal] load metadata for docker.io/library/busybox:latest                                                                                                                                              0.4s
 => [1/4] FROM docker.io/library/busybox@sha256:954e1f01e80ce09d0887ff6ea10b13a812cb01932a0781d6b0cc23f743a874fd                                                                                               0.0s
 => [internal] load build context                                                                                                                                                                              0.2s
 => => transferring context: 70B                                                                                                                                                                               0.0s
 => CACHED [2/4] COPY ./one /one                                                                                                                                                                               0.0s
 => CACHED [3/4] COPY ./two /two                                                                                                                                                                               0.0s
 => CACHED [4/4] COPY ./three /three                                                                                                                                                                           0.0s
 => exporting to image                                                                                                                                                                                         0.3s
 => => exporting layers                                                                                                                                                                                        0.0s
 => => writing image sha256:cc706b1284cd4e0ff50fb9338f9202e4a769c9a435a139ecc3b0f4a34c7ac977                                                                                                                   0.0s
 => => naming to docker.io/library/busybox-squashed                                                                                                                                                            0.0s
root@8be8a791847f:~/test# docker image inspect --format '{{json .RootFS.Layers}}'  busybox-squashed 
["sha256:0b97b1c81a3200e9eeb87f17a5d25a50791a16fa08fc41eb94ad15f26516ccea","sha256:0486fd605761a4fafd88bcac8f3c99df5abf1cda0160f71548ef730e03ab4449"]

  1. squash with legacy builder
root@8be8a791847f:~/test# docker build --squash -t busybox-squashed -f- . <<EOF
FROM busybox
COPY ./one /one
COPY ./two /two
COPY ./three /three
EOF

Sending build context to Docker daemon  7.215kB
Step 1/4 : FROM busybox
latest: Pulling from library/busybox
fc1a6b909f82: Already exists 
Digest: sha256:954e1f01e80ce09d0887ff6ea10b13a812cb01932a0781d6b0cc23f743a874fd
Status: Downloaded newer image for busybox:latest
 ---> af2f74c517aa
Step 2/4 : COPY ./one /one
 ---> 82189394f4fd
Step 3/4 : COPY ./two /two
 ---> e39967575c25
Step 4/4 : COPY ./three /three
 ---> 4d46acf12033
Successfully built 9a6defb57473
Successfully tagged busybox-squashed:latest
root@8be8a791847f:~/test# docker image inspect --format '{{json .RootFS.Layers}}'  busybox-squashed 
["sha256:0b97b1c81a3200e9eeb87f17a5d25a50791a16fa08fc41eb94ad15f26516ccea","sha256:0486fd605761a4fafd88bcac8f3c99df5abf1cda0160f71548ef730e03ab4449"]

- Description for the changelog

- A picture of a cute animal (not mandatory but encouraged)

Signed-off-by: Stepan Blyshchak <stepanblischak@gmail.com>
Signed-off-by: Stepan Blyshchak <stepanblischak@gmail.com>
func(i int, tp *specs.Platform) {
eg.Go(func() error {
st, img, err := dockerfile2llb.Dockerfile2LLB(ctx, dtDockerfile, dockerfile2llb.ConvertOpt{
st, img, baseImg, err := dockerfile2llb.Dockerfile2LLB(ctx, dtDockerfile, dockerfile2llb.ConvertOpt{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW; the changes made in the vendor directory should be upstreamed too github.com/moby/buildkit.

I'll add a needs-vendoring label

@thaJeztah
Copy link
Member

ping @tonistiigi @AkihiroSuda PTAL

@thaJeztah
Copy link
Member

ping @tonistiigi @AkihiroSuda PTAL

@thaJeztah thaJeztah added the kind/bugfix PR's that fix bugs label Oct 10, 2019
@andrewhsu
Copy link
Contributor

Looks like this PR needs more work to be taken out of draft mode. @Blyschak you still working on this or should it be closed?

@thaJeztah
Copy link
Member

perhaps @tonistiigi could have a look what's needed; I think a fix is still desirable to get feature parity

@kiorky
Copy link
Contributor

kiorky commented Nov 14, 2020

Another related problem trying to solve the need to keep the squashing up to the FROM layer:

I'm currently using buildkit to build the image, and then still relying on legacy builder to squash it

To reproduce, just do

echo | DOCKER_BUILDKIT=1 docker build -t a -<<EOF
FROM busybox
RUN touch foo
RUN touch foo2
RUN touch foo3
EOF
echo "FROM a"| DOCKER_BUILDKIT="" docker build --squash -t b -

I tried with to build an image with docker:20.10.0-beta1-dind and DOCKER_BUILDKIT= which fails with

docker build --squash -t *** -
Error response from daemon: experimental session with v1 builder is no longer supported,
use builder version v2 (BuildKit) instead

The same is working with current docker:dind

@thaJeztah
Copy link
Member

The error about experimental session ("Error response from daemon: experimental session with v1 builder is no longer supported...") is unrelated; that error is fixed in #41648, which will be in the next beta/rc of docker 20.10

@fredcooke
Copy link

This needs reviving. How can I help??? Keen to see this over the line as it's critical for me to have --squash and docker claims the old engine is going to be removed with zero for. buildkit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DOCKER_BUILDKIT=1 docker build --squash should not squash the base image

8 participants