dateo. Coding Blog

Coding, Tech and Developers Blog

.NET 7
ASP.NET
Blazor
Docker

How to publish .NET 7 apps directly to Docker

Dennis Frühauff on November 17th, 2022

With .NET 7 being around for only a couple of days now, there are plenty of new features to be played with.
One of these is the actual ability of .NET's build infrastructure to directly publish your applications to a Docker container registry (or any other container registry, for that matter), without having to explicitly specify a Docker file.


Containerization is everywhere around us. And, to be honest, many among us are not yet comfortable working with Docker or similar tools (that's probably why there are so many container orchestration systems out there trying to make our life easier). Anyway, with .NET 7 on everyone's lips right now as well, I thought it might be cool to explore one of the new features the latest SDK provides us with.


So let's see how we can deploy a .NET 7 application directly to Docker using only built-in framework tooling. For this, I am using my Windows 11 machine with Docker installed.


Creating a simple application

First, let's create a simple application that lets us see later that everything is working correctly. In order to do this, I am in my scratch directory issuing PowerShell commands to the .NET CLI. With the following command, we'll create a Blazor application:


 dotnet new blazorserver -o MvcToDocker --no-https

Once that is done, switch to the newly created directory and run


dotnet watch

The SDK will build your project, start up a browser and show your application. The watch command will also watch for any changes on your file system, causing the page to hot-reload while you are working on your site. Pretty neat.


  MvcToDocker -> D:\repos\sandbox\MvcToDocker\bin\Debug\net6.0\MvcToDocker.dll
dotnet watch 🚀 Started
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5020
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: D:\repos\sandbox\MvcToDocker\
dotnet watch ⌚ File changed: .\Pages\Index.razor.
dotnet watch 🔥 Hot reload of changes succeeded.

In order to see an actual change on the page once we switch from hosting on Windows to hosting in a Docker container, let's change the content of the index.razor to be:


@page "/"  
  
<PageTitle>Index</PageTitle>  
  
<h1>Hello, world!</h1>  
  
@operatingSystem  
  
@code {  
    private string operatingSystem;  
    protected override void OnInitialized()  
    {  
        operatingSystem = Environment.OSVersion.ToString();  
        base.OnInitialized();  
    }  
}

Ideally, your application now displays something like this:
Screenshot 1


Preparing the containerization support

The first thing we need to do to add containerization support to our application is install a NuGet package:


dotnet add package Microsoft.NET.Build.Containers

You can also do this from your favorite IDE. In any case, your .csproj will contain a line similar to this:


<ItemGroup>
  <PackageReference Include="Microsoft.NET.Build.Containers" Version="0.2.7" />  
</ItemGroup>  

We're pretty much ready to publish now. But let's make sure that our application and machine are ready for .NET 7. To see the list of installed SDKs, execute the following command and see if there is a .NET 7 version in it.


dotnet --list-sdks

If not, you will have to install it first. .NET 6 does not support publishing to container registries directly.


winget install Microsoft.DotNet.SDK.7

Also, make sure that the .csproj file references the correct framework:


<TargetFramework>net7.0</TargetFramework>

Publishing and running the app inside a container

To publish the application to the Docker container registry as an image, type the following command:


dotnet publish --os linux --arch x64 -p:PublishProfile=DefaultContainer /t:PublishContainer

We are telling the SDK to compile the application targeting a Linux-x64 file system using the profiles defined by the above NuGet package. Also, the resulting image will be directly registered in Docker. We can verify the result by running


docker images

which gives me:


REPOSITORY    TAG       IMAGE ID       CREATED              SIZE
mvctodocker   1.0.0     f03fb089f375   About a minute ago   213MB

Now, to run the image as a container, we can use the following command:


docker run -d -p 80:80 mvctodocker:1.0.0

Here, we are mapping the host's port 80 to the container's port 80 using the -p flag and detaching from the created container instance by using -d. If that is confusing to you, you might want to read one of the many Docker tutorials out there as well.


In any case, we are now ready to visit localhost:80 giving us the following result:
Screenshot 2
Since we changed the content of the index page, we can see that the application is indeed running on a local Linux environment.


If you scan through the bin/ directory that was created on your machine, you might notice that there is no Docker file involved in this process. The .NET SDK directly registered the corresponding image in the Docker registry.


You can also connect to different container registries, like remote Docker registries, or an Azure container registry. If you want to do this, you will have to set an environment variable DOCKER_HOST to specify a different containerization daemon for the SDK to use.


To me, this is a pretty cool feature making deployment of .NET apps very easy and straightforward. And for many, it might also be a reason to learn a bit more about Docker. You can host any number of applications on your local or remote machines, on Raspberry Pis even. Go give it a try and let me know what you think!



Please share on social media, stay in touch via the contact form, and subscribe to our post newsletter!

Be the first to know when a new post was released

We don’t spam!
Read our Privacy Policy for more info.

We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.