dotnet / dotnet-docker

Docker images for .NET and the .NET Tools.
https://hub.docker.com/_/microsoft-dotnet
MIT License
4.48k stars 1.94k forks source link

Segmentation fault building project on dotnet/sdk:7.0 image with Apple M1 #4225

Closed jon-mca closed 1 year ago

jon-mca commented 1 year ago

Describe the Bug

Running into a problem where creating a docker image from mcr.microsoft.com/dotnet/sdk:7.0 on an M1 Apple MacBook Pro throws a segmentation fault from package qemu during publish.

ERROR [publish 8/8] RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish --self-conta  6.7s
 > [publish 8/8] RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish --self-contained -r linux-x64:
#15 2.836 MSBuild version 17.4.0+18d5aef85 for .NET
#15 6.456 qemu: uncaught target signal 11 (Segmentation fault) - core dumped
#15 6.729 Segmentation fault

The docker file looks like this, which worked previously with the .NET Core 6 SDK image (changed to point to 7.0 images):

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS publish
WORKDIR /src
COPY [".", "."]
WORKDIR "/src/MyProject"
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish --self-contained -r linux-x64

FROM mcr.microsoft.com/dotnet/runtime-deps:7.0 AS final
WORKDIR /app
COPY --from=publish /app/publish .
EXPOSE 80
EXPOSE 443
ENTRYPOINT ["./MyProject"]

My suspicion is that the SDK 7.0 base image that is being pulled from docker is not the ARM64 tagged variant, .i.e. Linux Arm64, and what is being used is not compatiable with the the M1.

Steps to Reproduce

Run dockerfile on an M1 equipped Apple Mac computer.

Other Information

A workaround for this issue is to explicity set the SDK base image to use the Linux Arm64 (7.0-bullseye-slim-arm64v8) tagged SDK image:

FROM mcr.microsoft.com/dotnet/sdk:7.0-bullseye-slim-arm64v8 AS publish
WORKDIR /src
COPY [".", "."]
WORKDIR "/src/MyProject"
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish --self-contained -r linux-x64

FROM mcr.microsoft.com/dotnet/runtime-deps:7.0 AS final
WORKDIR /app
COPY --from=publish /app/publish .
EXPOSE 80
EXPOSE 443
ENTRYPOINT ["./MyProject"]

...or a better workaround example is to provide the tag to use via --build-arg and pass "7.0-bullseye-slim-arm64v8" as a value otherwise it'll default to "7.0":

ARG SDK_TAG=7.0
FROM mcr.microsoft.com/dotnet/sdk:${SDK_TAG} AS publish
WORKDIR /src
COPY [".", "."]
WORKDIR "/src/MyProject"
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish --self-contained -r linux-x64

FROM mcr.microsoft.com/dotnet/runtime-deps:7.0 AS final
WORKDIR /app
COPY --from=publish /app/publish .
EXPOSE 80
EXPOSE 443
ENTRYPOINT ["./MyProject"]

Output of docker version

Client: Docker Engine - Community
 Version:           20.10.21
 API version:       1.41
 Go version:        go1.19.2
 Git commit:        baeda1f82a
 Built:             Tue Oct 25 17:53:02 2022
 OS/Arch:           darwin/arm64
 Context:           desktop-linux
 Experimental:      true

Server: Docker Desktop 4.14.1 (91661)
 Engine:
  Version:          20.10.21
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.7
  Git commit:       3056208
  Built:            Tue Oct 25 17:59:41 2022
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.6.9
  GitCommit:        1c90a442489720eec95342e1789ee8a5e1b9536f
 runc:
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Output of docker info

Client:
 Context:    desktop-linux
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc., v0.9.1)
  compose: Docker Compose (Docker Inc., v2.12.2)
  dev: Docker Dev Environments (Docker Inc., v0.0.3)
  extension: Manages Docker extensions (Docker Inc., v0.2.13)
  sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc., 0.6.0)
  scan: Docker Scan (Docker Inc., v0.21.0)

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 17
 Server Version: 20.10.21
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 1c90a442489720eec95342e1789ee8a5e1b9536f
 runc version: v1.1.4-0-g5fd4c4d
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
  cgroupns
 Kernel Version: 5.15.49-linuxkit
 Operating System: Docker Desktop
 OSType: linux
 Architecture: aarch64
 CPUs: 6
 Total Memory: 7.765GiB
 Name: docker-desktop
 ID: CNTH:R6D7:QFEW:INEF:X2VS:DWGM:JCQF:HCQG:OO3S:J4P2:J7YX:A4XF
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  hubproxy.docker.internal:5000
  127.0.0.0/8
 Live Restore Enabled: false
dotnet-issue-labeler[bot] commented 1 year ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

mthalman commented 1 year ago

My suspicion is that the SDK 7.0 base image that is being pulled from docker is not the ARM64 tagged variant, .i.e. Linux Arm64, and what is being used is not compatiable with the the M1.

This can be verified by including the following instruction to be executed within the SDK container:

RUN dotnet --info

That will indicate the architecture in the output. If it's not getting the Arm64 image, that's related to Docker and not the 7.0 tag. You can see that the 7.0 tag is configured to serve up an Arm64 image:

> docker manifest inspect mcr.microsoft.com/dotnet/sdk:7.0
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 2009,
         "digest": "sha256:77f18f87a309d53015601a388f0108e8e0742b98cade2ba5276605799e662b09",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 2009,
         "digest": "sha256:a47ea685326c54067b7819d00bf0cb03e98e56c202bbbab22a4bb249cb2977d5",
         "platform": {
            "architecture": "arm",
            "os": "linux",
            "variant": "v7"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 2008,
         "digest": "sha256:37062ef2dc44d9e3f4d82632c28702833d7578ae9da4cf40ff52a080e844bd48",
         "platform": {
            "architecture": "arm64",
            "os": "linux",
            "variant": "v8"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 3854,
         "digest": "sha256:03f882c3dbb4ac697ff9fe4191d4892144318836986bf95f5b7dc67813b8861d",
         "platform": {
            "architecture": "amd64",
            "os": "windows",
            "os.version": "10.0.17763.3650"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 3855,
         "digest": "sha256:4cff7618d17797f0e9bfe534890564a98326c98260f434a953ff340c5f8eb5d1",
         "platform": {
            "architecture": "amd64",
            "os": "windows",
            "os.version": "10.0.20348.1249"
         }
      }
   ]
}

Is your M1 machine running Docker Desktop for Apple Silicon as opposed to Intel via emulation? See https://docs.docker.com/desktop/install/mac-install/.

Note that you can explicitly configure which architecture is targeted when you pull an image as well by using docker pull --platform linux/arm64 mcr.microsoft.com/dotnet/sdk:7.0.

crodriguesbr commented 1 year ago

HI! I have the same problem. Running directly on the Apple M2, my program runs correctly, but if I put the same compiled program inside a container, I get the Segment Fault message. Any idea?

My Settings Dockerfile FROM mcr.microsoft.com/dotnet/aspnet:7.0-alpine3.16-arm64v8

Build dotnet build --no-restore --configuration Release

Publish dotnet publish --no-restore --no-build --configuration Release --output /publish

jon-mca commented 1 year ago

Hi @mthalman,

Thanks for getting back to me, I get what you are saying although working with the 6.0 SDK image I didn't need to do configure docker to explicity only pull down the Arm64 variants of the image that is registered in the manifest where it would appear it resolves the correct one automatically although I'll need to prove this by what you suggest with getting what the dotnet --info outputs.

I'll get back to you, thanks for your help.

jon-mca commented 1 year ago

Also re-installed docker targeting Apple Silicon just to be on the safe side in case I mistakenly installed the intel based one just so you know.

PeterHagen commented 1 year ago

I use docker buildx to create the linux container on M1. This worked fine on .Net 6 with adding -p "linux/amd64" as parameters. With .Net 7 I get a segmentation fault exception on doing dotnet restore or build. When I remove the explicit platform parameter, it does build the image, but I can't run it on linux. The logs say: exec /usr/bin/dotnet: exec format error. I expect this to be the same issue.

mthalman commented 1 year ago

@PeterHagen - Can you include RUN dotnet -info in your Dockerfile as part of the SDK stage? I'd like to know the output of that.

richlander commented 1 year ago

This writeup may help: https://github.com/dotnet/dotnet-docker/discussions/3848

PeterHagen commented 1 year ago

@PeterHagen - Can you include RUN dotnet -info in your Dockerfile as part of the SDK stage? I'd like to know the output of that.

Here you go:

#7 [ 3/13] RUN dotnet --info
#7 2.525 .NET SDK:
#7 2.526  Version:   7.0.100
#7 2.526  Commit:    e12b7af219
#7 2.527 
#7 2.527 Runtime Environment:
#7 2.539  OS Name:     debian
#7 2.539  OS Version:  11
#7 2.557  OS Platform: Linux
#7 2.651  RID:         debian.11-x64
#7 2.651  Base Path:   /usr/share/dotnet/sdk/7.0.100/
#7 2.664 
#7 2.664 Host:
#7 2.664   Version:      7.0.0
#7 2.664   Architecture: x64
#7 2.664   Commit:       d099f075e4
#7 2.664 
#7 2.664 .NET SDKs installed:
#7 2.664   7.0.100 [/usr/share/dotnet/sdk]
#7 2.664 
#7 2.664 .NET runtimes installed:
#7 2.664   Microsoft.AspNetCore.App 7.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
#7 2.664   Microsoft.NETCore.App 7.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
#7 2.664 
#7 2.664 Other architectures found:
#7 2.664   None
#7 2.664 
#7 2.664 Environment variables:
#7 2.664   Not set
#7 2.664 
#7 2.664 global.json file:
#7 2.664   Not found
#7 2.664 
#7 2.664 Learn more:
#7 2.664   https://aka.ms/dotnet/info
#7 2.664 
#7 2.664 Download .NET:
#7 2.664   https://aka.ms/dotnet/download
mthalman commented 1 year ago

@PeterHagen - What gets output when you execute this command: docker run --rm debian uname -a

crodriguesbr commented 1 year ago

I found my problem, using strace. I had included in my Dockerfile the Datadog APM Agent for alpine because my dotnet base image was alpine for ARM64, I changed it to the debian image and changed the Datadot APM Agent as well. It worked correctly. I'm using buildx to generate the image build.

PeterHagen commented 1 year ago

@PeterHagen - What gets output when you execute this command: docker run --rm debian uname -a

here you go:

% docker run --rm debian uname -a
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
4948a51a9a3f: Pull complete 
Digest: sha256:a288aa7ad0e4d443e86843972c25a02f99e9ad6ee589dd764895b2c3f5a8340b
Status: Downloaded newer image for debian:latest
Linux 97a985292e36 5.15.49-linuxkit #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022 aarch64 GNU/Linux
mthalman commented 1 year ago

@PeterHagen - What gets output when you execute this command: docker run --rm debian uname -a

here you go:

% docker run --rm debian uname -a
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
4948a51a9a3f: Pull complete 
Digest: sha256:a288aa7ad0e4d443e86843972c25a02f99e9ad6ee589dd764895b2c3f5a8340b
Status: Downloaded newer image for debian:latest
Linux 97a985292e36 5.15.49-linuxkit #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022 aarch64 GNU/Linux

@PeterHagen - And what happens when you run this?

docker pull mcr.microsoft.com/dotnet/sdk:7.0
docker run --rm mcr.microsoft.com/dotnet/sdk:7.0 uname -a
docker run --rm mcr.microsoft.com/dotnet/sdk:7.0 dotnet --info
PeterHagen commented 1 year ago

@PeterHagen - What gets output when you execute this command: docker run --rm debian uname -a

here you go:

% docker run --rm debian uname -a
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
4948a51a9a3f: Pull complete 
Digest: sha256:a288aa7ad0e4d443e86843972c25a02f99e9ad6ee589dd764895b2c3f5a8340b
Status: Downloaded newer image for debian:latest
Linux 97a985292e36 5.15.49-linuxkit #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022 aarch64 GNU/Linux

@PeterHagen - And what happens when you run this?

docker pull mcr.microsoft.com/dotnet/sdk:7.0
docker run --rm mcr.microsoft.com/dotnet/sdk:7.0 uname -a
docker run --rm mcr.microsoft.com/dotnet/sdk:7.0 dotnet --info
% docker pull mcr.microsoft.com/dotnet/sdk:7.0
docker run --rm mcr.microsoft.com/dotnet/sdk:7.0 uname -a
docker run --rm mcr.microsoft.com/dotnet/sdk:7.0 dotnet --info
7.0: Pulling from dotnet/sdk
Digest: sha256:c6c842afe9350ac32fe23188b81d3233a6aebc33d0a569d565f928c4ff8966e1
Status: Image is up to date for mcr.microsoft.com/dotnet/sdk:7.0
mcr.microsoft.com/dotnet/sdk:7.0
Linux 668c7fd7b213 5.15.49-linuxkit #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022 aarch64 GNU/Linux
.NET SDK:
 Version:   7.0.100
 Commit:    e12b7af219

Runtime Environment:
 OS Name:     debian
 OS Version:  11
 OS Platform: Linux
 RID:         debian.11-arm64
 Base Path:   /usr/share/dotnet/sdk/7.0.100/

Host:
  Version:      7.0.0
  Architecture: arm64
  Commit:       d099f075e4

.NET SDKs installed:
  7.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 7.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 7.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

This looks OK to me, but the issue happens when I use docker buildx with platform specification for linux x64.

mthalman commented 1 year ago

This looks OK to me, but the issue happens when I use docker buildx with platform specification for linux x64.

@PeterHagen - Oh, I didn't realize that. Then yes, there's a regression there. I believe it is https://github.com/NuGet/Home/issues/12227. It's just the reverse architectures of what is described there. That issue describes arm64 container on a x64 host. But your scenario is x64 container on an arm64 host. In both cases, QEMU emulation is being used with different symptoms, but the underlying issue is identified by https://github.com/NuGet/Home/issues/12227. Please follow up there.

My original assumption was that you were having the same symptoms as @jon-mca which is somehow getting the incorrect architecture of the .NET SDK image. In the case of @jon-mca, it's getting a x64 container when an arm64 container is expected. That then leads to the regression of https://github.com/NuGet/Home/issues/12227. But that regression can be avoided if you avoid emulation altogether and use an arm64 container on an arm64 host.

@jon-mca - Do you have any update to give regarding your issue. Did the reinstall of Docker Desktop help? If not, can you follow up with results of the output from what I posted at https://github.com/dotnet/dotnet-docker/issues/4225#issuecomment-1339632207 and https://github.com/dotnet/dotnet-docker/issues/4225#issuecomment-1340974621.

TrieBr commented 1 year ago

I'm also experiencing this issue on Mac M1 but I found a workaround. Using an arm64 image for building/publishing but using an amd64 image for the ASP runtime seems to work well.

jon-mca commented 1 year ago

Apologies @mthalman, been swamped with work.

I did re-install docker desktop and made sure it was tailored for Apple silicon as noted here: https://desktop.docker.com/mac/main/arm64/Docker.dmg

Here is a dump of the docker version and info related stuff as asked when submitting a ticket: Docker version

Client: Docker Engine - Community
 Version:           20.10.21
 API version:       1.41
 Go version:        go1.19.2
 Git commit:        baeda1f82a
 Built:             Tue Oct 25 17:53:02 2022
 OS/Arch:           darwin/arm64
 Context:           default
 Experimental:      true

Server: Docker Desktop 4.14.1 (91661)
 Engine:
  Version:          20.10.21
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.7
  Git commit:       3056208
  Built:            Tue Oct 25 17:59:41 2022
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.6.9
  GitCommit:        1c90a442489720eec95342e1789ee8a5e1b9536f
 runc:
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Docker Info

Client:
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc., v0.9.1)
  compose: Docker Compose (Docker Inc., v2.12.2)
  dev: Docker Dev Environments (Docker Inc., v0.0.3)
  extension: Manages Docker extensions (Docker Inc., v0.2.13)
  sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc., 0.6.0)
  scan: Docker Scan (Docker Inc., v0.21.0)

Server:
 Containers: 1
  Running: 0
  Paused: 0
  Stopped: 1
 Images: 33
 Server Version: 20.10.21
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 1c90a442489720eec95342e1789ee8a5e1b9536f
 runc version: v1.1.4-0-g5fd4c4d
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
  cgroupns
 Kernel Version: 5.15.49-linuxkit
 Operating System: Docker Desktop
 OSType: linux
 Architecture: aarch64
 CPUs: 6
 Total Memory: 7.765GiB
 Name: docker-desktop
 ID: ARGG:C4EB:Q7BX:5DLS:DRSW:K7K7:7HJV:VWTA:AU4J:GDF4:OSJI:VH2D
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  hubproxy.docker.internal:5000
  127.0.0.0/8
 Live Restore Enabled: false

Running the commands suggested to get the relevant info from dotnet:

7.0: Pulling from dotnet/sdk
Digest: sha256:c6c842afe9350ac32fe23188b81d3233a6aebc33d0a569d565f928c4ff8966e1
Status: Image is up to date for mcr.microsoft.com/dotnet/sdk:7.0
mcr.microsoft.com/dotnet/sdk:7.0
Linux fbb9ed3105fe 5.15.49-linuxkit #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022 aarch64 GNU/Linux
.NET SDK:
 Version:   7.0.100
 Commit:    e12b7af219

Runtime Environment:
 OS Name:     debian
 OS Version:  11
 OS Platform: Linux
 RID:         debian.11-arm64
 Base Path:   /usr/share/dotnet/sdk/7.0.100/

Host:
  Version:      7.0.0
  Architecture: arm64
  Commit:       d099f075e4

.NET SDKs installed:
  7.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 7.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 7.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

I did re-try an existing project that was experiencing the segmentation fault using the basline 7.0 SDK image and failed (redacted with MyProject):

=> CACHED [publish 5/6] WORKDIR /src/MyProject 0.0s
 => ERROR [publish 6/6] RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish --sel  6.5s
------
 > [publish 6/6] RUN dotnet publish MyProject.csproj" -c Release -o /app/publish --self-contained -r linux-x64:
#13 2.757 MSBuild version 17.4.0+18d5aef85 for .NET
#13 6.210 qemu: uncaught target signal 11 (Segmentation fault) - core dumped
#13 6.485 Segmentation fault
------
executor failed running [/bin/sh -c dotnet publish "MyProject.csproj" -c Release -o /app/publish --self-contained -r linux-x64]: exit code: 139
Write-Error: Something went wrong building the application in docker. Please review any error messages output above

@mthalman let me know if you need more info.

mthalman commented 1 year ago

@jon-mca - What's the docker build command you're using when this error occurs?

jon-mca commented 1 year ago

@mthalman I'm using the build command like this: docker build . --platform "linux/amd64" -f "/path/to/dockerfile" -t "some-docker-repo.io/some-image:some-tag"

mthalman commented 1 year ago

@mthalman I'm using the build command like this: docker build . --platform "linux/amd64" -f "/path/to/dockerfile" -t "some-docker-repo.io/some-image:some-tag"

Ok. So I was confused because of this from your original post:

My suspicion is that the SDK 7.0 base image that is being pulled from docker is not the ARM64 tagged variant, .i.e. Linux Arm64, and what is being used is not compatiable with the the M1.

Based on that, I was thinking you were explicitly wanting the Arm64 version of the image. But by passing --platform "linux/amd64", you're explicitly getting the AMD64 version of the image. That leads to the regression identified in https://github.com/NuGet/Home/issues/12227. Note that the NuGet issue as it's written is about an Arm64 container on an x64 host but the reverse scenario is also an issue because both scenarios use emulation.

Can I ask why you're explicitly setting the platform of the docker build to linux/amd64? There should be no reason to do that. It's causing emulation to occur which leads to that regression. If you simply omit the use of the --platform option, you should get the Arm64 version of the image which is perfectly capable of publishing x64 apps which you've already configured with -r linux-x64.

Based on this, I'm going to close this issue because https://github.com/NuGet/Home/issues/12227 is the underlying issue to be followed up on if you require the use of emulation.

PeterHagen commented 1 year ago

Can I ask why you're explicitly setting the platform of the docker build to linux/amd64? There should be no reason to do that. It's causing emulation to occur which leads to that regression. If you simply omit the use of the --platform option, you should get the Arm64 version of the image which is perfectly capable of publishing x64 apps which you've already configured with -r linux-x64.

I use this to build a container to push to a x64 linux server, not to run it on the M1 machine. Without the platform instruction, it won't run on that server. Doing the same thing on an Intel Mac, it does work, so this is my fallback for now.

mthalman commented 1 year ago

Can I ask why you're explicitly setting the platform of the docker build to linux/amd64? There should be no reason to do that. It's causing emulation to occur which leads to that regression. If you simply omit the use of the --platform option, you should get the Arm64 version of the image which is perfectly capable of publishing x64 apps which you've already configured with -r linux-x64.

I use this to build a container to push to a x64 linux server, not to run it on the M1 machine. Without the platform instruction, it won't run on that server.

If you have an explicit architecture that you're targeting, you can use that architecture in the tag of the runtime/aspnet image. For example, this sample Dockerfile uses a multi-arch tag for the SDK image but an architecture-specific tag for the runtime image.

Here's a snippet showing the relevant pieces:

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build

RUN dotnet publish -c Release -o /app -r linux-x64 --self-contained false --no-restore

FROM mcr.microsoft.com/dotnet/runtime:7.0-bullseye-slim-amd64

If you build that on an M1 machine without specifying the --platform option, it will use the Arm64 version of the SDK image but it will produce an application image that is for AMD64.

jon-mca commented 1 year ago

Apologies @mthalman, I was responding after working a long day yesterday and neglected to give context.

Probably too late now being the issue is closed but I'll eleborate nonetheless, for local development we have our of own instance an environment in Azure running applications using linux/x64 Container Apps but we use our M1 macs to build and push images to that environment rather than using a CI/CD process.

The docker build steps are this for SDK 6.0:

For SDK 7.0, I'm having to explicity set to use the arm64 image for the publish step which we didn't need to when using SDK 6.0:

We can't change --platform to use arm64 as the destination, in Azure, is configured for x64.

Fair enough if this ticket will remain closed and again I apologise for the confusion my previous response caused.

Kind regards

mthalman commented 1 year ago

@jon-mca - See my recommendation here: https://github.com/dotnet/dotnet-docker/issues/4225#issuecomment-1347398138. That's the preferred pattern to follow because it has true multi-arch support. The same Dockerfile will be able to be built from an x64 or Arm64 machine without any use of the --platform option.

PeterHagen commented 1 year ago

Apologies @mthalman, I was responding after working a long day yesterday and neglected to give context.

Probably too late now being the issue is closed but I'll eleborate nonetheless, for local development we have our of own instance an environment in Azure running applications using linux/x64 Container Apps but we use our M1 macs to build and push images to that environment rather than using a CI/CD process.

For SDK 7.0, I'm having to explicity set to use the arm64 image for the publish step which we didn't need to when using Here's a snippet showing the relevant pieces:

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build

RUN dotnet publish -c Release -o /app -r linux-x64 --self-contained false --no-restore

FROM mcr.microsoft.com/dotnet/runtime:7.0-bullseye-slim-amd64

If you build that on an M1 machine without specifying the --platform option, it will use the Arm64 version of the SDK image but it will produce an application image that is for AMD64.

I got it to work, by using the mcr.microsoft.com/dotnet/runtime:7.0-bullseye-slim-amd64 image, but without specifying the platform for the docker buildx, or the dotnet publish.

Thanks for the info!

tpitman commented 1 year ago

Apologies @mthalman, I was responding after working a long day yesterday and neglected to give context. Probably too late now being the issue is closed but I'll eleborate nonetheless, for local development we have our of own instance an environment in Azure running applications using linux/x64 Container Apps but we use our M1 macs to build and push images to that environment rather than using a CI/CD process. For SDK 7.0, I'm having to explicity set to use the arm64 image for the publish step which we didn't need to when using Here's a snippet showing the relevant pieces:

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build

RUN dotnet publish -c Release -o /app -r linux-x64 --self-contained false --no-restore

FROM mcr.microsoft.com/dotnet/runtime:7.0-bullseye-slim-amd64

If you build that on an M1 machine without specifying the --platform option, it will use the Arm64 version of the SDK image but it will produce an application image that is for AMD64.

I got it to work, by using the mcr.microsoft.com/dotnet/runtime:7.0-bullseye-slim-amd64 image, but without specifying the platform for the docker buildx, or the dotnet publish.

Thanks for the info!

If you do it that way do you end up with a linux/amd64 image?

jrajini commented 1 year ago

@PeterHagen can you please share your docker file? Appreciate the help.

PeterHagen commented 1 year ago

Sure. This is how I use it now:

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS BUILD-WEB-APP
ENV DEBIAN_FRONTEND noninteractive
ENV TZ=Europe/Amsterdam
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
WORKDIR /app

COPY NuGet.config /app/
COPY id_rsa /app/
COPY build-settings /app/
COPY build-setup /app/

RUN     echo "Setup" && \
        chmod +x /app/build-setup && \
        /app/build-setup

# copy these files late to keep cache
COPY default-functions /app/
COPY build-dotnet /app/
COPY build-commithash /app/

RUN     echo "Start build" && \
        chmod +x /app/build-dotnet && \
        /app/build-dotnet

# Create image
FROM mcr.microsoft.com/dotnet/aspnet:7.0-bullseye-slim-amd64
WORKDIR /app
ENV DEBIAN_FRONTEND noninteractive
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
ENV TZ=Europe/Amsterdam
ENV ASPNETCORE_URLS=http://+:5000
ENV ASPNETCORE_ENVIRONMENT="Production"
ENV CMS_PRIVATE_STORAGE=/opt/data/private
ENV CMS_PUBLIC_CACHE=/opt/data/cache
COPY appsettings.production.json /app/appsettings.json
COPY --from=BUILD-WEB-APP /opt/data/bin /app
EXPOSE 5000
ENTRYPOINT ["dotnet", "My.app.dll"]

I build it like this, without specifying the platform. If I do use --platform "linux/amd64", it won't work:

docker buildx build -f "${DOCKERFILE}" -t "${IMAGE}" .)
jrajini commented 1 year ago

Thank you @PeterHagen . This is great.

kyawzaymoore commented 1 year ago

using this image in dotnet run time docker image and command line docker build -t imagename . work mcr.microsoft.com/dotnet/runtime:7.0-bullseye-slim-amd64

Peder2911 commented 1 year ago

I was having this issue as well. It was solved by downgrading to dotnet sdk 6.0.

Peder2911 commented 1 year ago

I have to say that I am not very impressed when seeing that you guys just closed this issue. Leaving a potential segfault "in the wild" like this should not happen.

mthalman commented 1 year ago

@Peder2911 - The segfault is caused by .NET's interaction with QEMU which is not a supported configuration (see https://github.com/dotnet/core/pull/8163).

Please read through this blog post which provides the details on getting this to correctly work without using QEMU: https://devblogs.microsoft.com/dotnet/improving-multiplatform-container-support/

Peder2911 commented 1 year ago

Hey! Sorry for my rash comment, I was really frustrated with this after many long hours yesterday. Thank you for your work on this!

mauroao commented 5 months ago

Can I ask why you're explicitly setting the platform of the docker build to linux/amd64? There should be no reason to do that. It's causing emulation to occur which leads to that regression. If you simply omit the use of the --platform option, you should get the Arm64 version of the image which is perfectly capable of publishing x64 apps which you've already configured with -r linux-x64.

I use this to build a container to push to a x64 linux server, not to run it on the M1 machine. Without the platform instruction, it won't run on that server.

If you have an explicit architecture that you're targeting, you can use that architecture in the tag of the runtime/aspnet image. For example, this sample Dockerfile uses a multi-arch tag for the SDK image but an architecture-specific tag for the runtime image.

Here's a snippet showing the relevant pieces:

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build

RUN dotnet publish -c Release -o /app -r linux-x64 --self-contained false --no-restore

FROM mcr.microsoft.com/dotnet/runtime:7.0-bullseye-slim-amd64

If you build that on an M1 machine without specifying the --platform option, it will use the Arm64 version of the SDK image but it will produce an application image that is for AMD64.

Worked for me ! Thank you a lot !!!