Docker and NativeAOT

Andrii Kurdiumov
2 min readJul 4, 2021
Whale jumping from the water to look at NativeAOT

Today I will have only partially interesting article I believe. My wife stuck in Montenegro with kids, because she forget to take COVID test, and I have to magically pull additional tickets from somewhere. That’s was a bit of stress for me, so I have limited time to setup proper experiment.

Enough explanations, let’s start to business. I decide to run NativeAOT on Docker. Obviously that’s not interesting enough, since that would work in same way as it would work on Linux. So to make things a bit spicier, I decide to run Hello World on the scratch image. Practical aspects of that experiment I leave out of discussion for now. It’s not related to NativeAOT and usually answer same as answer to other related questions: Do I need run my Rust application on scratch image? or Do I need run my Go application on scratch image? If your requirements answer yes to you, go ahead, and know that your best-friend .NET allow you do do that.

Honestly I do not start from scratch in that experiment, and just update already existing work Adeel Mujahid, Jan Vorlicek and Christian Scheuer. These guys make that scenario works in CoreRT, and I just update it to work in NativeAOT.

So based on their work, I already knew that I need
- Statically linked image
- Application running on linux-musl-x64
- Build that on Alpine with musl

So once I realize what’s needed, Dockerfile quickly pops-up

Since I need statically compile application, I add <StaticallyLinked>true</StaticallyLinked> to the project file.

Now after publishing regular HelloWorld application, you will have 17Mb Docker image.

If you run application in reflection-free mode, then you will have image of only 7Mb size.

Final changes to project file.

So that’s all what is needed to make C# application run on scratch image.

Again, if you want more conservative approach and do not go that far with scratch image, just run your WebApp using NativeAOT compiler, by default sample works. That way you can package application using techniques for regular .NET applications, just do not forget to add <PackageReference Include=”Microsoft.DotNet.ILCompiler” Version=”6.0.0-*” />.

Source code for this sample located at https://github.com/kant2002/NativeAOTDocker so you can start playing immidiately.

--

--

Andrii Kurdiumov

Math lover, lost in the woods of software development