Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

buildkit: normalize build target and local platform #42951

Merged
merged 1 commit into from Oct 20, 2021

Conversation

crazy-max
Copy link
Member

Fixes #42893
Fixes docker/buildx#795
Fixes docker/for-mac#6009

- What I did
When resolving a local reference to build an image with BuildKit, we need to normalize the two platforms (reference and target platform) before matching them otherwise it would fallback to remote and fail with:

[+] Building 1.9s (3/3) FINISHED                                                                                                                                                                      
 => [internal] load build definition from Dockerfile.child                                                                                                                                       0.1s
 => => transferring dockerfile: 102B                                                                                                                                                             0.0s
 => [internal] load .dockerignore                                                                                                                                                                0.1s
 => => transferring context: 2B                                                                                                                                                                  0.0s
 => ERROR [internal] load metadata for docker.io/local/foo-parent:latest                                                                                                                         1.3s
------
 > [internal] load metadata for docker.io/local/foo-parent:latest:
------
error: failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to create LLB definition: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed

If we check daemon logs we have:

Requested build platform linux/arm64 does not match local image platform linux/arm64/v8, checking remote

- How I did it
Normalize local and target platform before matching them.

- How to verify it

On M1 host:

# ./Dockerfile.foo
FROM alpine
RUN echo "Hello foo!"
# ./Dockerfile.bar
FROM local/foo-parent
RUN echo "Hello bar!"
DOCKER_BUILDKIT=1 docker build -f Dockerfile.foo -t local/foo-parent .
DOCKER_BUILDKIT=1 docker build -f Dockerfile.bar -t local/foo-child .

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

cc @thaJeztah @tonistiigi

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
@thaJeztah thaJeztah added this to the 21.xx milestone Oct 20, 2021
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM

@thaJeztah
Copy link
Member

Failures are unrelated (and most should now be fixed on master)

@jrajahalme
Copy link

@crazy-max This still fails if using "docker buildx build --load" on both build commands. Is that by design? If so, is there a way to use local images with buildx?

$ DOCKER_BUILDKIT=1 docker buildx build --load -f Dockerfile.foo -t local/foo-parent .
[+] Building 0.4s (7/7) FINISHED                                                                                                  
 => [internal] load build definition from Dockerfile.foo                                                                     0.0s
 => => transferring dockerfile: 76B                                                                                          0.0s
 => [internal] load .dockerignore                                                                                            0.0s
 => => transferring context: 2B                                                                                              0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                             0.2s
 => [1/2] FROM docker.io/library/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300              0.0s
 => => resolve docker.io/library/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300              0.0s
 => CACHED [2/2] RUN echo "Hello foo!"                                                                                       0.0s
 => exporting to oci image format                                                                                            0.1s
 => => exporting layers                                                                                                      0.0s
 => => exporting manifest sha256:415006142ad68915792e13feb34a71379d880a946666fab8f578bedd8922135e                            0.0s
 => => exporting config sha256:08a75c04c63fa34b43445d21ae662336e88d9e0c4f77907959d3e82a3738b5a5                              0.0s
 => => sending tarball                                                                                                       0.1s
 => importing to docker
$ DOCKER_BUILDKIT=1 docker buildx build --load -f Dockerfile.bar -t local/foo-child .[+] Building 1.4s (3/3) FINISHED                                                                                                  
 => [internal] load build definition from Dockerfile.bar                                                                     0.0s
 => => transferring dockerfile: 86B                                                                                          0.0s
 => [internal] load .dockerignore                                                                                            0.0s
 => => transferring context: 2B                                                                                              0.0s
 => ERROR [internal] load metadata for docker.io/local/foo-parent:latest                                                     1.3s
------
 > [internal] load metadata for docker.io/local/foo-parent:latest:
------
Dockerfile.bar:1
--------------------
   1 | >>> FROM local/foo-parent
   2 |     RUN echo "Hello bar!"
   3 |     
--------------------
error: failed to solve: local/foo-parent: pull access denied, repository does not exist or may require authorization: authorization status: 401: authorization failed

@nikophil
Copy link

nikophil commented Apr 8, 2022

Hello I still got this bug as well @crazy-max @thaJeztah

$ docker --version
Docker version 20.10.14, build a224086
$ docker buildx version
github.com/docker/buildx v0.8.1-docker 5fac64c2c49dae1320f2b51f1a899ca451935554
# Dockerfile.foo
FROM alpine
RUN echo "Hello foo!"
# Dockerfile.bar
FROM foo:local
RUN echo "Hello bar!"
docker buildx build \
     --load \
     --tag foo:local \
     --file ./Dockerfile.foo \
     .

docker buildx build \
     --load \
     --file ./Dockerfile.bar \
     .
=> ERROR [internal] load metadata for docker.io/library/foo:local                                                                                                                                                                       1.1s
------
 > [internal] load metadata for docker.io/library/foo:local:
------
Dockerfile.bar:1
--------------------
   1 | >>> FROM foo:local
   2 |     RUN echo "Hello bar!"
   3 |     
--------------------
error: failed to solve: foo:local: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
$ docker images | grep foo
foo                                         local                                      2f58ace52d56   About a minute ago   5.57MB

@thaJeztah
Copy link
Member

Note that docker --version shows the version information of the CLI only, not the daemon; what does docker version show?

Also, from your command (docker buildx build --load) are you using a custom builder (using the container driver, not the BuildKit embedded in the docker daemon)? What does docker buildx ls show?

@nikophil
Copy link

@thaJeztah

$ docker version
Client: Docker Engine - Community
 Version:           20.10.14
 API version:       1.41
 Go version:        go1.16.15
 Git commit:        a224086
 Built:             Thu Mar 24 01:48:02 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.14
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.15
  Git commit:       87a90dc
  Built:            Thu Mar 24 01:45:53 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.5.11
  GitCommit:        3df54a852345ae127d1fa3092b95168e4a88e2f8
 runc:
  Version:          1.0.3
  GitCommit:        v1.0.3-0-gf46b6ba
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
$ docker buildx ls
NAME/NODE               DRIVER/ENDPOINT             STATUS   PLATFORMS
blissful_nightingale    docker-container                     
  blissful_nightingale0 unix:///var/run/docker.sock inactive 
cranky_panini           docker-container                     
  cranky_panini0        unix:///var/run/docker.sock inactive 
elated_vaughan          docker-container                     
  elated_vaughan0       unix:///var/run/docker.sock inactive 
hungry_elgamal          docker-container                     
  hungry_elgamal0       unix:///var/run/docker.sock inactive 
naughty_almeida         docker-container                     
  naughty_almeida0      unix:///var/run/docker.sock inactive 
stupefied_snyder        docker-container                     
  stupefied_snyder0     unix:///var/run/docker.sock inactive 
vigilant_hamilton *     docker-container                     
  vigilant_hamilton0    unix:///var/run/docker.sock stopped  
xenodochial_darwin      docker-container                     
  xenodochial_darwin0   unix:///var/run/docker.sock inactive 
default                 docker                               
  default               default                     running  linux/amd64, linux/386

The problem occurs on my local machine, but it also occurs on github actions, where we use docker/setup-buildx-action action (with option: buildkitd-flags: "cache=enabled")

@thaJeztah
Copy link
Member

From the docker buildx ls output, it looks like you're using a container builder as the current builder. Container builders are designed to be stateless; they only preserve build-cache, but not images (i.e., they are designed to not depend on any previous state), so the second build fails, because the foo:local image is only available in the Docker daemon image store, and not known to the builder instance. See moby/buildkit#2343 for a longer discussion about the design.

@nikophil
Copy link

nikophil commented Apr 12, 2022

Thanks @thaJeztah this resolves my problem 🎉

@contentfree
Copy link

contentfree commented Sep 25, 2023

This still fails with docker build in v24.0.6 on Mac M1. Workaround is to use DOCKER_BUILDKIT=0 (which is deprecated, I believe) or to ensure that your parent image is built supporting the required arm64 platform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants