docker / buildx

Docker CLI plugin for extended build capabilities with BuildKit
Apache License 2.0
3.33k stars 448 forks source link

Ability to silence WARN: "Requested platforms $BUILDPLATFORM do not match result platforms $PLATFORMS" for cross compilation steps #2563

Closed BenTheElder closed 2 days ago

BenTheElder commented 3 days ago

Description

I use stages like this: FROM --platform=$BUILDPLATFORM $BASE_IMAGE AS go-build

In multi-stage buildx builds to enable speedy cross-compliation of go binaries before copying them into another stage for the target platform.

At some point buildx started producing warnings like this:

WARN: Requested platforms linux/amd64 do not match result platforms linux/amd64,linux/arm64

Can we have some way to acknowledge and silence these warnings so users running the build don't see WARN that is expected? Maybe something like:

# nowarn=platform # we're cross compiling, this is expected
FROM --platform=$BUILDPLATFORM $BASE_IMAGE AS go-build
tonistiigi commented 2 days ago

What is the full example of the build and arguments that you are building. The warning should only be shown if you export image with the wrong architecture in the end of the build, not when you use an intermediate stage for your native architecture as part of the build.

tonistiigi commented 2 days ago

WARN: Requested platforms linux/amd64 do not match result platforms linux/amd64,linux/arm64

Actually this should mean that you ran buildx build --platform=linux/amd64 but got a multi-platform image as a result?

BenTheElder commented 2 days ago

Thanks for the response!

The warning should only be shown if you export image with the wrong architecture in the end of the build, not when you use an intermediate stage for your native architecture as part of the build.

I must be missing something, I see this when not setting output and when setting --push

What is the full example of the build and arguments that you are building.

I'm seeing this when running: docker buildx build --platform=linux/amd64,linux/arm64 with full arguments:

docker buildx build --platform=linux/amd64,linux/arm64 --progress=auto -t gcr.io/k8s-staging-kind/local-path-provisioner:v20240702-79ffb678 --pull --build-arg GO_VERSION=1.22.4 --build-arg=VERSION=v0.0.24 .

In this case it's via make -C images/local-path-provisioner in https://github.com/kubernetes-sigs/kind

Sources here: https://github.com/kubernetes-sigs/kind/tree/main/images/local-path-provisioner

At the end I get:

=> WARN: Requested platforms linux/amd64 do not match result platforms linux/amd64,linux/arm64 0.0s

I also see this when using the push make target which sets --push (you could try this by setting REGISTRY to somewhere you can push to)

BenTheElder commented 2 days ago

Guessing now that the solution then is to set an explicit FROM --platform for the final stage when using FROM --platform for other stages? I had assumed it would implicitly be the target platform if not specified 😅

EDIT: no, that does not do it:

$ git diff --cached
diff --git a/images/local-path-provisioner/Dockerfile b/images/local-path-provisioner/Dockerfile
index e4c4d717..f4f58c48 100644
--- a/images/local-path-provisioner/Dockerfile
+++ b/images/local-path-provisioner/Dockerfile
@@ -28,7 +28,7 @@ RUN eval "$(gimme "${GO_VERSION}")" \
     && GOBIN=/usr/local/bin go install github.com/google/go-licenses@latest \
     && GOARCH=$TARGETARCH go-licenses save --save_path=/_LICENSES .

-FROM gcr.io/distroless/base-debian11
+FROM --platform=$TARGETPLATFORM gcr.io/distroless/base-debian11
 COPY --from=0 /usr/local/bin/local-path-provisioner /usr/local/bin/local-path-provisioner
 COPY --from=0 /_LICENSES/* /LICENSES/
 COPY --chmod=0644 files/LICENSES/* /LICENSES/*

$ make -C images/local-path-provisioner
make: Entering directory '/usr/local/google/home/bentheelder/go/src/sigs.k8s.io/kind/images/local-path-provisioner'
./../../hack/build/init-buildx.sh
docker buildx build --platform=linux/amd64,linux/arm64  --progress=auto -t gcr.io/k8s-staging-kind/local-path-provisioner:v20240703-79ffb678-dirty --pull --build-arg GO_VERSION=1.22.4 --build-arg=VERSION=v0.0.24 .
WARNING: No output specified with docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load

[elided normal build output]

 => WARN: Requested platforms linux/amd64 do not match result platforms linux/amd64,linux/arm64                                                                                                                                                                   0.0s
tonistiigi commented 2 days ago

Hmm, I can't reproduce this.

» docker buildx build --platform=linux/amd64,linux/arm64  --progress=auto -t gcr.io/k8s-staging-kind/local-path-provisioner:v20240702-79ffb678 --pull --build-arg GO_VERSION=1.22.4 --build-arg=VERSION=v0.0.24 -o type=oci . > t.tar
[+] Building 1.1s (20/20) FINISHED                                                                                                                docker-container:practical_einstein
 => [internal] load build definition from Dockerfile                                                                                                                             0.0s
 => => transferring dockerfile: 1.65kB                                                                                                                                           0.0s
 => [linux/arm64 internal] load metadata for gcr.io/distroless/base-debian11:latest                                                                                              0.3s
 => [linux/arm64 internal] load metadata for docker.io/library/golang:latest                                                                                                     0.6s
 => [linux/amd64 internal] load metadata for gcr.io/distroless/base-debian11:latest                                                                                              0.5s
 => [internal] load .dockerignore                                                                                                                                                0.0s
 => => transferring context: 2B                                                                                                                                                  0.0s
 => [linux/arm64 stage-0 1/4] FROM docker.io/library/golang:latest@sha256:74cd6cd2c52b2fb7d9076899aabcfdf7dd827694c6f344697af4ada6f99cb3bb                                       0.1s
 => => resolve docker.io/library/golang:latest@sha256:74cd6cd2c52b2fb7d9076899aabcfdf7dd827694c6f344697af4ada6f99cb3bb                                                           0.1s
 => [linux/amd64 stage-1 1/4] FROM gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97                                0.1s
 => => resolve gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97                                                    0.1s
 => [linux/arm64 stage-1 1/4] FROM gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97                                0.1s
 => => resolve gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97                                                    0.0s
 => [internal] load build context                                                                                                                                                0.0s
 => => transferring context: 269B                                                                                                                                                0.0s
 => CACHED [linux/arm64 stage-0 2/4] COPY --chmod=0755 scripts/third_party/gimme/gimme /usr/local/bin/                                                                           0.0s
 => CACHED [linux/arm64 stage-0 3/4] RUN git clone --filter=tree:0 https://github.com/rancher/local-path-provisioner                                                             0.0s
 => CACHED [linux/arm64->amd64 stage-0 4/4] RUN eval "$(gimme "1.22.4")"     && export GOTOOLCHAIN="go1.22.4"     && cd local-path-provisioner     && git fetch && git checkout  0.0s
 => CACHED [linux/amd64 stage-1 2/4] COPY --from=0 /usr/local/bin/local-path-provisioner /usr/local/bin/local-path-provisioner                                                   0.0s
 => CACHED [linux/amd64 stage-1 3/4] COPY --from=0 /_LICENSES/* /LICENSES/                                                                                                       0.0s
 => CACHED [linux/amd64 stage-1 4/4] COPY --chmod=0644 files/LICENSES/* /LICENSES/*                                                                                              0.0s
 => CACHED [linux/arm64 stage-0 4/4] RUN eval "$(gimme "1.22.4")"     && export GOTOOLCHAIN="go1.22.4"     && cd local-path-provisioner     && git fetch && git checkout "v0.0.  0.0s
 => CACHED [linux/arm64 stage-1 2/4] COPY --from=0 /usr/local/bin/local-path-provisioner /usr/local/bin/local-path-provisioner                                                   0.0s
 => CACHED [linux/arm64 stage-1 3/4] COPY --from=0 /_LICENSES/* /LICENSES/                                                                                                       0.0s
 => CACHED [linux/arm64 stage-1 4/4] COPY --chmod=0644 files/LICENSES/* /LICENSES/*                                                                                              0.0s
 => exporting to oci image format                                                                                                                                                0.2s
 => => exporting layers                                                                                                                                                          0.0s
 => => exporting manifest sha256:8a1e8f53c5877ecf13b66f2146c41ba86eab58d1780b56695e15d718061de78a                                                                                0.0s
 => => exporting config sha256:7c64354cab0ba6291817c97ab0bbff54c1ca3a1a7944a899f6f96a97f266f909                                                                                  0.0s
 => => exporting attestation manifest sha256:600cfd99af78fc52f678e3eee2d7868cbb5c70809398b51ae69f1f00d0a82a67                                                                    0.0s
 => => exporting manifest sha256:3f8d05d94c7c127d2da52a49bb298a86f546f97c2508faeab22e7976674024df                                                                                0.0s
 => => exporting config sha256:1f1bec12e63c53ec3d9d1b656c2b9ea149d84a070610c90716e001a214044260                                                                                  0.0s
 => => exporting attestation manifest sha256:ca4ac7f5ec35bd947218fe87020db7e1e42109bd814009bfcc0175615e377d66                                                                    0.0s
 => => exporting manifest list sha256:032cb39d80c9e2886fd65ea796f081461dc5310787f62b1f9487ae31ca18b3c2                                                                           0.0s
 => => sending tarball                                                                                                                                                           0.2s

View build details: docker-desktop://dashboard/build/practical_einstein/practical_einstein0/tp36hrgpfi69nbebuqde581nx

 1 warning found (use --debug to expand):
 - JSONArgsRecommended: JSON arguments recommended for ENTRYPOINT to prevent unintended behavior related to OS signals (line 35)
``` » docker buildx build --platform=linux/amd64,linux/arm64 --progress=auto -t gcr.io/k8s-staging-kind/local-path-provisioner:v20240702-79ffb678 --pull --build-arg GO_VERSION=1.22.4 --build-arg=VERSION=v0.0.24 . [+] Building 0.7s (19/19) FINISHED docker-container:practical_einstein => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 1.72kB 0.0s => [linux/arm64 internal] load metadata for gcr.io/distroless/base-debian11:latest 0.3s => [linux/arm64 internal] load metadata for docker.io/library/golang:latest 0.5s => [linux/amd64 internal] load metadata for gcr.io/distroless/base-debian11:latest 0.5s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [linux/arm64 stage-1 1/4] FROM gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97 0.1s => => resolve gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97 0.1s => [linux/arm64 stage-0 1/4] FROM docker.io/library/golang:latest@sha256:74cd6cd2c52b2fb7d9076899aabcfdf7dd827694c6f344697af4ada6f99cb3bb 0.1s => => resolve docker.io/library/golang:latest@sha256:74cd6cd2c52b2fb7d9076899aabcfdf7dd827694c6f344697af4ada6f99cb3bb 0.1s => [internal] load build context 0.0s => => transferring context: 269B 0.0s => [linux/amd64 stage-1 1/4] FROM gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97 0.1s => => resolve gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97 0.0s => CACHED [linux/arm64 stage-0 2/4] COPY --chmod=0755 scripts/third_party/gimme/gimme /usr/local/bin/ 0.0s => CACHED [linux/arm64 stage-0 3/4] RUN git clone --filter=tree:0 https://github.com/rancher/local-path-provisioner 0.0s => CACHED [linux/arm64 stage-0 4/4] RUN eval "$(gimme "1.22.4")" && export GOTOOLCHAIN="go1.22.4" && cd local-path-provisioner && git fetch && git checkout "v0.0. 0.0s => CACHED [linux/arm64 stage-1 2/4] COPY --from=0 /usr/local/bin/local-path-provisioner /usr/local/bin/local-path-provisioner 0.0s => CACHED [linux/arm64 stage-1 3/4] COPY --from=0 /_LICENSES/* /LICENSES/ 0.0s => CACHED [linux/arm64 stage-1 4/4] COPY --chmod=0644 files/LICENSES/* /LICENSES/* 0.0s => CACHED [linux/arm64->amd64 stage-0 4/4] RUN eval "$(gimme "1.22.4")" && export GOTOOLCHAIN="go1.22.4" && cd local-path-provisioner && git fetch && git checkout 0.0s => CACHED [linux/amd64 stage-1 2/4] COPY --from=0 /usr/local/bin/local-path-provisioner /usr/local/bin/local-path-provisioner 0.0s => CACHED [linux/amd64 stage-1 3/4] COPY --from=0 /_LICENSES/* /LICENSES/ 0.0s => CACHED [linux/amd64 stage-1 4/4] COPY --chmod=0644 files/LICENSES/* /LICENSES/* 0.0s WARNING: No output specified with docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load View build details: docker-desktop://dashboard/build/practical_einstein/practical_einstein0/e8nq1k2nz717j1rmwdem7t8vp 1 warning found (use --debug to expand): - JSONArgsRecommended: JSON arguments recommended for ENTRYPOINT to prevent unintended behavior related to OS signals (line 35) ```

I wonder if maybe you are using Docker driver and you already have single arch gcr.io/distroless/base-debian11 in docker images ? Do you see multiple pulls of debian11 for each arch in progress like I have:

 => [linux/amd64 stage-1 1/4] FROM gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97                                0.1s
 => => resolve gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97                                                    0.1s
 => [linux/arm64 stage-1 1/4] FROM gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97                                0.1s
 => => resolve gcr.io/distroless/base-debian11:latest@sha256:2fb55308ef768a0ca0851f294d7f5b582579dba6522d1d2162e2d5f33b876e97                                                    0.0s

Guessing now that the solution then is to set an explicit FROM --platform for the final stage

No, that is not required. No platform means --platform=$TARGETPLATFORM

Post docker buildx version and docker buildx inspect to see if there is any config difference.

BenTheElder commented 2 days ago

Do you see multiple pulls of debian11 for each arch in progress like I have:

I see a resolve for each and it appears (?) to pull them if I docker buildx rm before building again.

Post docker buildx version and docker buildx inspect to see if there is any config difference.

$ docker buildx version
github.com/docker/buildx v0.9.1-docker ed00243a0ce2a0aee75311b06e32d33b44729689

$ docker buildx inspect
Name:   kind-builder
Driver: docker-container

Nodes:
Name:      kind-builder0
Endpoint:  unix:///var/run/docker.sock
Status:    running
Buildkit:  v0.14.1
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6

... this made me realize how old the system managed buildx install is (docker-ce-cli ~~5:20.10.21 from Google's rodete / GLinux mirror), so I installed v0.15.1 under $HOME/.docker/cli-plugins instead and now I can't replicate this.

So sorry for the noise. I'll follow up about getting our packages updated ...

BenTheElder commented 2 days ago

P.S. Thank your buildx, it's really nice :-)