Scott Hanselman on Programming, The Web, Open Source,. NET, The Cloud and More. Scott Hanselman. There is a great post from Steve Laster in 2. ASP. NET Docker Image sizes. Since then Docker has added multi stage build files so you can do more in one Dockerfile. Containers are about easy and reliable deployment, and theyre also about density. The topic is very easy and i am sure that lots of java programmer already know how to compile java program existing in package. However there are users who frequently. You want to use as little memory as possible, sure, but it also is nice to make them as small as possible so youre not spending time moving them around the network. The size of the image file can also affect startup time for the container. Plus its just tidy. Ive been building a little 6 node Raspberry Pi ARM Kubenetes Cluster on my desk like you do this week, and I noticed that my image sizes were a little larger than Id like. This is a bigger issue because its a relatively low powered system, but again, why carry around x unnecessary megabytes if you dont have to Alex Ellis has a great blog on building. NET Core apps for Raspberry Pi along with a You. Ultimate Soccer Manager 98 Iso more. Tube video. In his video and blog he builds a Console. Write. Line console app, which is great for Open. Faas open source serverless platform but I wanted to also have ASP. NET Core apps on my Raspberry Pi k. Tutorial Openproj Pdf'>Tutorial Openproj Pdf. He included this as a challenge in his blog, so challenge accepted Thanks for all your help and support, Alex ASP. NET Core on Docker on ARMFirst I make a basic ASP. NET Core app. I could do a Web API, but this time Ill do an MVC one with Razor Pages. To be clear, they are the same thing just with different starting points. UltiDev-Cassini-Web-Server-for-ASP-Net-2-0_3.png' alt='Run External Program .Net' title='Run External Program .Net' />I can always add pages or add JSON to either, later. I start with dotnet new mvc or dotnet new razor, etc. Im going to be running this in Docker, managed by Kuberenetes, and while I can always change the Web. Host in Program. cs to change how the Kestrel web server starts up like this Web. Host. Create. Default. Builderargs. Use. Run External Program .Net' title='Run External Program .Net' />Urlshttp 5. For Docker use cases its easier to change the listening URL with an Environment Variable. Sure, it could be 8. I like 5. 00. 0. Ill set the ASPNETCOREURLS environment variable to http 5. I make the Dockerfile. Optimized Multi. Stage Dockerfile for ASP. NETTheres a number of right ways to do this, so youll want to think about your scenarios. Youll see below that Im using ARM because Raspberry Pi so if you see errors running your container like qemu Unsupported syscall 3. ARM image on x. 86x. EHlaWbe2XY/maxresdefault.jpg' alt='Run External Program .Net' title='Run External Program .Net' />Im going to be building an ARM container from Windows but I cant run it here. I have to push it to a container registry and then tell my Raspberry Pi cluster to pull it down and THEN itll run, over there. Heres what I have so far. NOTE there are some things commented out, so be conscious. This iswas a learning exercise for me. Dont you copypaste unless you know whats up And if theres a mistake, heres a Git. Hub Gist of my Dockerfile for you to change and improve. Its important to understand that. NET Core has an SDK with build tools and development kits and compilers and stuff, and then it has a runtime. The runtime doesnt have the make an app stuff, it only has the run an app stuff. There is not currently an SDK for ARM so thats a limitation that we are somewhat elegantly working around with the multistage build file. But, even if there WAS an SDK for ARM, wed still want to use a Dockerfile like this because its more efficient with space and makes a smaller image. Lets break this down. There are two stages. The first FROM is the SDK image that builds the code. Were doing the build inside Docker which is lovely, and great reliable way to do builds. PRO TIP Docker is smart about making intermediate images and doing the least work, but its useful if we the authors do the right thing as well to help it out. For example, see where we COPY the. Often youll see folks do a COPY. That doesnt allow Docker to detect whats changed and youll end up paying for the restore on EVERY BUILD. By making this two steps copy the project, restore, copy the code, this means your dotnet restore intermediate step will be cached by Docker and things will be WAY faster. After you build, youll do a publish. If you know the destination like I do linux arm you can do a RID runtime id publish that is self contained with r linux arm or debian, or whatever and youll get a complete self contained version of your app. Otherwise, you can just publish your apps code and use a. NET Core runtime image to run it. Since Im using a complete self contained build for this image, it would be overkill to ALSO include the. NET runtime. If you look at the Docker hub for Microsoftdotnet Youll see images called deps for dependencies. Those are images that sit on top of debian that include the things. NET needs to run but not. NET itself. The stack of images looks generally like this for exampleFROM debian stretch. FROM microsoftdotnet 2. FROM microsoftdotnet 2. So you have your base image, your dependencies, and your. NET runtime. The SDK image would include even more stuff since it needs to build code. Again, thats why we use that for the as builder image and then copy out the results of the compile and put them in another runtime image. You get the best of all worlds. FROM microsoftdotnet 2. RUN mkdir p rootsrcappaspnetcoreapp. WORKDIR rootsrcappaspnetcoreappcopy just the project file over this prevents additional extraneous restores and allows us to re use the intermediate layer This only happens again if we change the csproj. This means WAY faster buildsCOPY aspnetcoreapp. Because we have a custom nuget. COPY nuget. config. RUN dotnet restore. COPY. RUN dotnet publish c release o published r linux arm Smaller Best for apps with self contained. NETs, as it doesnt include the runtime It has the ependenciesto run. NET Apps. The. NET runtime image sits on this. FROM microsoftdotnet 2. Bigger Best for apps. NETs that arent self contained. FROM microsoftdotnet 2. These are the non ARM images. FROM microsoftdotnet 2. FROM microsoftdotnet 2. WORKDIR root COPY frombuilder rootsrcappaspnetcoreapppublished. ENV ASPNETCOREURLShttp 5. EXPOSE 5. 00. 0tcp This runs your app with the dotnet exe included with the runtime or SDKCMD dotnet,. This runs your self contained. NET Core app. You built with r to get this. CMD. aspnetcoreapp Notice also that I have a custom nuget. Ive included by commented out a bunch of the FROMs in the second stage. Im using just the ARM one, but I wanted you to see the others. Once we have the code we build copied into our runtime image, we set our environment variable so our all listens on port 5. Then we run our app. Notice that you can run it with dotnet foo. To sum up Build with FROM microsoftdotnet 2. Copy the results out to a runtime. Use the right runtime FROM for you. Right CPU architectureUsing the. NET Runtime typical or using a self contained build less soListening on the right port if a web app Running your app successfully and correctly Do you have a. Super important for. NET Builds, as you dont want to copy over obj, bin, etc, but you do want published. Optimizing a little more. There are a few pre release Tree Trimming tools that can look at your app and remove code and binaries that you are not calling. I included Microsoft. Packaging. Tools. Trimming as well to try it out and get even more unused code out of my final image by just adding a package to my project.