-
Notifications
You must be signed in to change notification settings - Fork 1.9k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
State of the art on using .NET + Docker + Apple M1 #3832
Comments
Note: On the Rosetta for Linux implementation present on macOS Ventura, .NET is functional.
I'd vote for approach 1. Servers on the cloud are not always x86 either. :) And then override via --platform when required, that's a task to be done by the user. |
Very nice! This is great to see. I specifically posted this here in the hope that I'd learn something. This is better than I was expecting. 100% agree on all your points. I guess I need to upgrade to Ventura! |
Got a cheatsheet on that @woachk? I installed Ventura but don't see a difference in behavior. I'm sure there is more to it. I looked around and didn't see any instructions anywhere. Also, why do you use |
@richlander the cheat sheet is at https://developer.apple.com/documentation/virtualization/running_intel_binaries_in_linux_vms_with_rosetta?language=objc and https://developer.apple.com/documentation/virtualization/running_gui_linux_in_a_virtual_machine_on_a_mac?language=objc for the overall VM test project. (Adding Rosetta tidbits to it is quite trivial, as explained on the Rosetta page) Docker Desktop didn’t pick that up yet (and i’m currently writing an alternative to it anyway, because of licensing reasons notably, but not only that.) Why I use sudo is because the account that I’m calling Docker from isn’t part of the docker group, and as such can’t communicate with the dockerd daemon otherwise. |
OK. I saw all that. I was wondering if there was something more productized from Docker. Good to know that I wasn't missing anything. OK, the usual reason for using Do you just install Docker on Linux (in the VM) and then re-direct your docker daemon to it? |
Yeah, I just ssh or execute directly from the VM. |
Oh. I see. I was fixated on docker desktop (for macOS). Thanks! |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
A friend of mine asked for an update on what the story was on using .NET container images on Apple M1, assuming your goal was to deploy to x64 services in Azure (or pick your cloud).
There are various challenges, some specific to .NET and others more general. Windows Arm64 (with x64 emulation) is likely identical to this.
Here's what you want:
Today, it is very easy to fall into an Arm64-centric experience on M1 (for any app plat, not just .NET) and then push an Arm64 image to your registry, and then realize it won't work on your x64 cloud hardware. And then you are not sure what happened. Ughh.
Docker desktop defaults to Arm64
Docker on Apple M1 defaults to native architecture, which is Arm64. If the images you are pulling are multi-arch, you'll pull Arm64. If they are single-arch (x64 or Arm64), you'll pull whatever that arch is. That's the right design choice, but also confusing if your deployment target in x64.
All .NET images are multi-arch. We want to enable using the same tags in a variety of environments. That's all good. It however means that you'll always get Arm64 images by default, on Apple M1 machines. Other app platforms will be the same.
I'll show you, using dotnetapp:
That's clearly Arm64. We can force building as x64.
That's x64. That's what we wanted for this scenario.
That error is coming from Docker. It's there to tell that you're using emulation.
If you want to live the x64 lifestyle on your Apple M1 machine, you need to use the
--platform linux/amd64
flag. Perhaps there is a way to enable amd64 as the default. I don't know..NET isn't supported in QEMU
The bigger issue is that .NET isn't supported in QEMU. QEMU is the emulator that Docker Desktop uses for emulation, on both x64 (to emulate Arm64) and Arm64 (to emulate x64) machines.
I'll show you the problem, using aspnetapp (building and running as x64):
That's not pretty. We're hoping this QEMU issue gets resolved.
Workaround 1
Use the multi-arch tags as intended, just like in the aspnetapp Dockerfile. Run .NET in containers as Arm64 in Apple M1. .NET has excellent fidelity across architectures so you will get an experience. If you want to deploy images to a registry, either build with
--platform linux/amd64
or build in a CI service like GitHub Actions. They will naturally build as x64.This approach 100% works. You get the best performance on Apple M1 and straightforward gestures. It's the no-compromises option, since emulated QEMU will always be a lot slower than native architecture.
Workaround 2
This workaround forces your Dockerfile to produce x64 assets by default. The SDK runs in whatever arch is chosen for
docker build
. It enables you to pivot the final image pretty easily with a--build-arg
. The intent of this is thatdocker build
will produce an asset that runs in your x64 cloud by default.I modified the aspnetapp Dockerfile a bit:
I added the two
ARG
lines at the start and added$TAG
in the lastFROM
statement. By default, this Dockerfile will produce x64 images by default, even when built on Apple M1 machines.However, if you build that image and
docker run
it, it will still fail, as I demonstrated earlier. If you want a good dev experience, you can opt into building and running it as Arm64.Like this:
% docker build --pull --build-arg ARCH=arm64v8 -t aspnetapp . % docker run --rm -p 8000:80 aspnetapp
That approach allows you to build an image on your M1 machine -- x64 by default -- and then push to a registry. For some folks, that's might be what they are looking for.
The text was updated successfully, but these errors were encountered: