Life's random bits By b1thunt3r (aka Ishan Jain)…
.NET Core Application in Docker

.NET Core Application in Docker

Ishan jain
Docker is getting very popular. It is also endorsed by Microsoft as the defacto container platform.

Disclaimer: Currently I am employed by Microsoft, but my views and thoughts are still my own. The reason I joined Microsoft was, the work Microsoft have been doing for last couple of years in Open Source Space. Today I am a advocate for Open Source representing Microsoft.

[ToC]

As the time goes, any popular technology is adopted by vendors. As such, Microsoft has adopted Docker as it now de-facto container platform, over its own Service Fabric. Both .NET Framework and .NET Core can be packaged inside a Docker container.

.NET Framework is has best performance inside a Windows container, which is still a preview in Azure Kubernetes Services. You can use Linux container for .NET Framework application by running it on top of Mono runtime, but the performance and compatibility might lack in some cases.

.NET Core on other hand is natively cross-platform. You can utilize official (well Mono is now also part of .NET Foundation, and official) .NET Core runtime in a Linux container.

Prerequisites

If you are not fully familiar with Docker, please consider reading my other posts on Docker:

In order to package and run a .NET Core application you will need:

  • .NET Core SDK
  • Docker

.NET Core Application

Create new application

To make it easier, I am just going to use the scaffolded Hello World console application. You can create a simple Hello World console application by:

dotnet new console --name hello

Note: dotnet-cli uses the current directory name as the project name. You can override it with --name <project name> argument.

Test the application

It is always a good idea to test the application, before we try to containerize it, just to make sure the application is working. If there is a problem down the road, we know it is with the container and not the application itself.

We can simply do a quick test by running the applications:

dotnet run

It should show a output like this:

Hello World!

Now that we know the application works, we can try to containerize it.

Note: When you run the project dotnet-cli will run dotnet restore and dotnet build before running the project.

Publish the project

When you publish the project, dotnet-cli will build the project an publish the output along with the any needed dependencies.

You can publish the project with:

dotnet publish -c Release

The argument -c Release makes sure that dotnet-cli will build the project in Release profile, without any Debug Symbols.

The main executable for this project will be hello.dll. dotnet-cli outputs by default a <project name>.dll, this can be overridden by configuring the .csproj file for the project.

dotnet-cli will publish the output to bin/Release/netcoreapp3.1/publish/ directory by default, this can be overridden by --output <directory> argument.

Note: Just like with dotnet run, when you publish the project dotnet-cli will run dotnet restore and dotnet build before published the project.

Docker

Create a DockerFile

Docker needs a docker file in order to build images and run these images in container. Dockerfile defines, how the image is build and how the content in the image can be executed.

We can simply create an empty file by:

On Windows

type nul > Dockerfile

On POSIX (Linux and macOS)

touch Dockerfile

Dockerfile content

Paste the following into the the newly created Dockerfile.

Note: Make sure to use the same runtime version as the SDK you have installed on your develpoment host.

FROM mcr.microsoft.com/dotnet/core/runtime:3.1
COPY bin/Release/netcoreapp3.1/publish/ App/
WORKDIR /App
ENTRYPOINT ["dotnet", "hello.dll"]

FROM tells the Docker to which base image to use. I am using a prebuilt .NET Core Runtime version 3.1.

COPY tells the Docker to copy content from the host to the image.

WORKDIR tells the Docker to switch to /App directory in the image. It is similar to cd command.

ENTRYPOINT tells Docker what to execute. In this we want to execute dotnet with the argument hello.dll, where hello.dll is compiled output's main executable.

Build the image

TO be able to use the image, we need to first build it.

docker build -t hello -f Dockerfile .

-t hello tells Docker to name the image with the name hello, so that it is easier to reference later on.

-f Dockerfile tells the Docker to use the Dockerfile as the build file. You can have several Dockerfiles in a single project, i.e. one for development and another for production.

Lastly . (the dot) tells the Docker to use current directory as the working directory. This is important if you are using the relative paths in the Dockerfile.

When we list all the images we can see the image was built:

docker images

The output will show you both the image you created, and the base image Docker downloaded to build your image.

REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
hello                                   latest              391bf79979b3        8 minutes ago       327MB
mcr.microsoft.com/dotnet/core/runtime   3.1                 b66ce51a57d5        3 weeks ago         327MB

Run the container

Now that was have a container image ready, we can create and run the container.

You can run the container with:

docker run -ti hello

-ti tells the Docker to run the container in TTY and interactive mode. You can use -d for running the application in background.

hello is the name of the image we want to run.

You should have a output like this:

Hello World!

tl;dr

As you can see it is very easy to run a .NET Core application inside a Docker container.
Keep in mind this post just highlights very quickly basic of how to run a Console application in Docker.