Cloud Concept Limited Logo

Publishing .NET Containers (Look No Dockerfile)

docker
Neil Tomlinson
#dotnet#.NET#Docker#howto

Publishing .NET Containers (Look No Dockerfile)

In dotnet we now have the ability to build a container using only the dotnet cli without the need for a Dockerfile. This capability is used in the Aspire project https://learn.microsoft.com/en-us/dotnet/aspire/ from Microsoft, which is an opinionated, cloud ready stack for building distributed applications. In this article we will just look at building and running a container for a web project and a console application.

Requirements

Create the mvc web app

dotnet new mvc --output container-app-web --name container-app-web
cd container-app-web
dotnet run
$ dotnet run
Building...
info: Microsoft.Hosting.Lifetime[14]
Now listening on: [http://localhost:5108](http://localhost:5108/)
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: /home/me/repositories/dotnet/container-app-web
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
Failed to determine the https port for redirect.

Visit the url logged in the console http://localhost:5108 to check it works

Publish and run the web app container

dotnet publish --os linux --arch x64 /t:PublishContainer -c Release
$ dotnet publish --os linux --arch x64 /t:PublishContainer -c Release
MSBuild version 17.8.5+b5265ef37 for .NET
Determining projects to restore...
Restored /home/me/repositories/dotnet/container-app-web/container-app-web.csproj (in 219 ms).
container-app-web -> /home/me/repositories/dotnet/container-app-web/bin/Release/net8.0/linux-x64/container-app-web.dll
container-app-web -> /home/me/repositories/dotnet/container-app-web/bin/Release/net8.0/linux-x64/publish/
Building image 'container-app-web' with tags 'latest' on top of base image '[mcr.microsoft.com/dotnet/aspnet:8.0](http://mcr.microsoft.com/dotnet/aspnet:8.0)'.
Pushed image 'container-app-web:latest' to local registry via 'docker'.

Run it with docker.

docker run -p 8080:8080 container-app-web:latest
$ docker run -p 8080:8080 container-app-web:latest
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
Storing keys in a directory '/home/app/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. For more information go to [https://aka.ms/aspnet/dataprotectionwarning](https://aka.ms/aspnet/dataprotectionwarning)
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
No XML encryptor configured. Key {2b48b911-d884-40e2-82ff-7e2a94e3a80b} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://[::]:8080
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /app

Visit http://localhost:8080 to try out the web app container

Create the .NET console app

To do the same thing for a console app we need to add the Microsoft.NET.Build.Containers package to the console project.

https://github.com/dotnet/sdk-container-builds/blob/main/docs/GettingStarted.md#build-a-container

dotnet new console --output container-console --name container-console
cd container-console
dotnet add package Microsoft.NET.Build.Containers
dotnet run

Publish and run the console container

There is a bit of discussion around needing to pass the command line switches differently for web and console apps but using the same command worked fine for me

dotnet publish --os linux --arch x64 /t:PublishContainer -c Release
$ dotnet publish --os linux --arch x64 /t:PublishContainer -c Release
MSBuild version 17.8.5+b5265ef37 for .NET
Determining projects to restore...
Restored /home/me/repositories/dotnet/container-console/container-console.csproj (in 484 ms).
container-console -> /home/me/repositories/dotnet/container-console/bin/Release/net8.0/linux-x64/container-console.dll
/home/me/.nuget/packages/microsoft.net.build.containers/8.0.204/build/Microsoft.NET.Build.Containers.targets(194,5): warning : Microsoft.NET.Build.Containers NuGet package is explicitly referenced. Consider removing the package reference to Microsoft.NET.Build.Containers as it is now part of .NET SDK. [/home/neil/repositories/dotnet/container-console/container-console.csproj]
container-console -> /home/me/repositories/dotnet/container-console/bin/Release/net8.0/linux-x64/publish/
Building image 'container-console' with tags 'latest' on top of base image '[mcr.microsoft.com/dotnet/runtime:8.0](http://mcr.microsoft.com/dotnet/runtime:8.0)'.
Pushed image 'container-console:latest' to local registry via 'docker'.

As you can see from the log output this publishes an image called container-console:latest which we can then run.

docker run container-console:latest

And below shows the result.

$ docker run container-console:latest
Hello, World!
$

Final thoughts

It is great that we have this capability without needing to learn how to write Dockerfiles. We also have ways to customise the container using the project file, as described here https://github.com/dotnet/sdk-container-builds/blob/main/docs/ContainerCustomization.md

← Back to Blog