Search code examples
dockerarmqemuarmv7armv6

How do you `docker buildx build` for ARM v6 on QEMU emulated platforms that present as arm7l to the build container?


When you build a Docker image with docker buildx build and specify '--platform=linux/arm/v6', the build container runs as arm7l rather than the expected arm6l, which creates issues if the build process assumes the observed CPU architecture is the actual target.

$ docker run -it --rm --platform linux/arm/6 debian /bin/arch
armv7l

When running a Docker image, one can set the environment variable QEMU_CPU to arm1176 as in:

$ docker run -it --rm --platform linux/arm/v6 -e QEMU_CPU=arm1176 debian /bin/arch 
armv6l

Resulting in armv6l, but that doesn't seem possible with docker build. Setting the QEMU_CPU varible before running docker buildx build will have no effect on the build container, and it'll still identify the CPU architecture as armv7l.

Is there a way to pass the QEMU_CPU variable down to the build container?

Added information:

Dockerfile where the issue was observed is at https://github.com/rbanffy/hercules-base/blob/6f16b9832465dc0de02841d94e91c4089cb6f586/Dockerfile

It reports internally observed architecture as well as target acquired from Docker buildx extension.

The exact command that exhibit the issue is:

docker buildx build -t rbanffy/hercules-base:latest-armv6 --platform=linux/arm/v6 --progress=plain .

In the builder output, it can be seen:

#8 0.712 TARGETPLATFORM is 'linux/arm/v6'
#8 0.717 TARGETARCH is 'arm'
#8 0.783 arch returns armv7l

Showing that TARGETPLATFORM and TARGETARCH are passed correctly, but the QEMU_CPU was not (resulting in it emulating armv7l).


Solution

  • Is there a way to pass the QEMU_CPU variable down to the build container?

    You can use a build arg.

    FROM debian
    
    ARG QEMU_CPU
    RUN /bin/arch >/arch.build
    CMD cat /arch.build
    
    $ docker buildx build -t test-arg --platform linux/arm/v6 --load .
    [+] Building 5.7s (7/7) FINISHED                                                                         
     => [internal] load build definition from df.build-arg                                              0.0s
     => => transferring dockerfile: 113B                                                                0.0s
     => [internal] load metadata for docker.io/library/debian:latest                                    0.4s
     => [internal] load .dockerignore                                                                   0.0s
     => => transferring context: 49B                                                                    0.0s
     => [1/2] FROM docker.io/library/debian:latest@sha256:fac2c0fd33e88dfd3bc88a872cfb78dcb167e74af616  4.3s
     => => resolve docker.io/library/debian:latest@sha256:fac2c0fd33e88dfd3bc88a872cfb78dcb167e74af616  0.0s
     => => sha256:ec3129b1f3b893a7412a0ac12044f811ed32ddf7028d374141819005f9d4699f 47.34MB / 47.34MB    3.2s
     => => extracting sha256:ec3129b1f3b893a7412a0ac12044f811ed32ddf7028d374141819005f9d4699f           1.0s
     => [2/2] RUN /bin/arch >/arch.build                                                                0.3s
     => exporting to docker image format                                                                0.5s
     => => exporting layers                                                                             0.2s
     => => exporting manifest sha256:158dccb11a903279aa2674f5f5b05d34306523c3e6dde9a562918dd5d98dc4a7   0.0s
     => => exporting config sha256:8016e60dac3fcf86203f639ecd26521546548de04523bbc6cd07e91867862544     0.0s
     => => sending tarball                                                                              0.3s
     => importing to docker                                                                             0.1s
    
    $ docker run test-arg
    WARNING: The requested image's platform (linux/arm/v6) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested
    armv7l
    
    $ docker buildx build -t test-arg --build-arg QEMU_CPU=arm1176 --platform linux/arm/v6 --load .
    [+] Building 1.0s (7/7) FINISHED                                                                         
     => [internal] load build definition from df.build-arg                                              0.0s
     => => transferring dockerfile: 113B                                                                0.0s
     => [internal] load metadata for docker.io/library/debian:latest                                    0.2s
     => [internal] load .dockerignore                                                                   0.0s
     => => transferring context: 49B                                                                    0.0s
     => CACHED [1/2] FROM docker.io/library/debian:latest@sha256:fac2c0fd33e88dfd3bc88a872cfb78dcb167e  0.0s
     => => resolve docker.io/library/debian:latest@sha256:fac2c0fd33e88dfd3bc88a872cfb78dcb167e74af616  0.0s
     => [2/2] RUN /bin/arch >/arch.build                                                                0.1s
     => exporting to docker image format                                                                0.5s
     => => exporting layers                                                                             0.1s
     => => exporting manifest sha256:6f88ebac9603ab863e8542a73ae0b14d9819a46b823e4edd65fb9e4b72f929f6   0.0s
     => => exporting config sha256:79626453e3a5de575563d53541ae9fb7d9d5627907f8c102e9aa2059b0c87d43     0.0s
     => => sending tarball                                                                              0.3s
     => importing to docker                                                                             0.1s
    
    $ docker run test-arg
    WARNING: The requested image's platform (linux/arm/v6) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested
    armv6l