Can't create dotnet arm64 image from docker hub automated build

Hello.

I try to build arm64 netcore app from docker hub automated build.

I created the next ‘pre_build’ hook:

#!/bin/bash
docker buildx create --name multiarch --use
docker buildx build --no-cache --platform linux/arm64 -f ./Dockerfile.arm64 -t $IMAGE_NAME .

Below, the ‘Dockerfile.arm64’ content:

FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build
ARG TARGETARCH
ARG BUILDPLATFORM
ADD . /app
WORKDIR /app
RUN dotnet restore "./ProxyVAD.csproj"
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
RUN dotnet publish "./ProxyVAD.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/aspnet:6.0-alpine
WORKDIR /app
COPY --from=build /app/publish /app
ENTRYPOINT ["dotnet", "ProxyVAD.dll"]

The build succeeds, but architecture image is amd64.
The same docker file used on linux VM on our lab create an arm64 arch image.

If I replace in the Dockerfile the line with dotnet restore with:
RUN dotnet restore "./ProxyVAD.csproj" -a $TARGETARCH

The build fails with the next error:

2025-04-15T15:26:46Z  > [linux/amd64->arm64 build 4/5] RUN dotnet restore "./ProxyVAD.csproj" -a arm64:
2025-04-15T15:26:46Z #0 0.819 MSBUILD : error MSB1001: Unknown switch.
2025-04-15T15:26:46Z #0 0.819     Full command line: '/usr/share/dotnet/sdk/6.0.428/MSBuild.dll -maxcpucount -verbosity:m -nologo -target:Restore ./ProxyVAD.csproj -a arm64 -distributedlogger:Microsoft.DotNet.Tools.MSBuild.MSBuildLogger,/usr/share/dotnet/sdk/6.0.428/dotnet.dll*Microsoft.DotNet.Tools.MSBuild.MSBuildForwardingLogger,/usr/share/dotnet/sdk/6.0.428/dotnet.dll'
2025-04-15T15:26:46Z #0 0.819   Switches appended by response files:
2025-04-15T15:26:46Z #0 0.819 Switch: -a
2025-04-15T15:26:46Z #0 0.819

What Am I missing ?

Kind regards.

Build platform will be the platform of the machine on which the build is running. So you will pull the amd64 image which could not produce an arm64 image. I guess you copied the code from the documentation but didn’t read the description before the code carefully. Here is the documentation

https://docs.docker.com/build/building/multi-platform/#cross-compilation

Here is the code:

# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log
FROM alpine
COPY --from=build /log /log

But here is what it describes before the code:

Depending on your project, if the programming language you use has good support for cross-compilation, you can leverage multi-stage builds to build binaries for target platforms from the native architecture of the builder. Special build arguments, such as BUILDPLATFORM and TARGETPLATFORM , are automatically available for use in your Dockerfile.

So the image will still be for the architecture of your machine and the compiler has to support cross-compiling for multiple architectures so you can copy the final binaries into an image based on the target architecture or into a scratch image. It is just to avoid emulation as also mentioned in the documentation

the FROM instruction is pinned to the native platform of the builder (using the --platform=$BUILDPLATFORM option) to prevent emulation from kicking in

If you want to emulate, then you can use

and set the platform option for the build command, but then you should not override it in the Dockerfile using BUILDPLATFORM.

I don’t know about this. It looks like a dotnet parameter issue which I’m not familiar with, but if dotnet can cross-compile that way, you need to figure out how it expects the platform architecture parameter.

Does that VM have an arm64 CPU?

EDIT:

After checking the dotnet documentation I see it should support the -a option, so maybe it is a version compatibility issue

https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-restore#options

Although it say:

Available since .NET 6 Preview 7.

EDIT2:

Oh, and I noticed you use buildplatform in the final stage as well, where you should have targetplatform or nothing.

I am having trouble too