Build once, run everywhere with .NET Core and Docker

Alberto De Natale
4 min readMar 15, 2020

--

One of the biggest conundrum when developing software that the industry is slowing trying to overcome is how to move code that has dependencies on other code, from one machine to another, without losing pieces of it along the way.

.NET took a big step forward in the past as it provided a runtime that could be easily installed on any Windows machine and would easily provide all the dependencies needed for the code to run.

Before it, the industry was reliant on COM Components. COM Components were heavily dependent on the machine they were running on. They were creating folders, modifying registries. They did not provide an easy way to specify a version.

That was not enough and became evident that something more was needed.

Not too long ago I remember creating my first .NET Core API. Unfortunately, the production server we were using did not have the .NET Core runtime installed.

Permissions are another example that comes in my mind. Forgetting to configure them could make for a long bug to be fixed in production.

The industry is trying to take another big step forward and we are shifting to “build once, run everywhere” by providing an easy way to create images that may be run inside “lightweight virtual machines” referred to as containers.

In this article, I will create a .NET Core API from scratch and I will dockerize it without using Visual Studio.

That will mean creating a Dockerfile manually that will result in a container running a simple .NET Core API.

The API

The API that I will use is the default one created when running the following command:

dotnet new api

The builder container

The first task that Docker will need to perform will be instantiating a container with the .NET Core SDK inside and build the source code.

In order to that, the image we need will have to come with .NET Core SDK shipped into it.

This image contains the .NET Core SDK which is comprised of three parts:

.NET Core CLI

.NET Core

ASP.NET Core

Use this image for your development process (developing, building and testing applications)

The first section out Dockerfile will look like follows:

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /source
# restore nuget packages
COPY *.csproj .
RUN dotnet restore
# copy source code
COPY . .
# build the source code using the SDK
RUN dotnet publish -c release -o /executable --no-restore

At the end of it, nuget will have restored the package folder and our executables will be stored inside the “executable” folder.

The runtime container

The second step will be instructing Docker to take the executable, move it into the runner container and start the dotnet CLI using it.

# runs the deployable using a separate image
# that is shipped with the .NET Runtime
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=build /executable .
ENTRYPOINT ["dotnet", "backend.dll"]

The image used at this stage is:

Running the container

The image defined by the Dockerfile needs to be built and then run into a container.

It can be built using the following command:

docker build . -t backend

This will generate an image that will be stored on your local machine. You may see a list of all images installed by running:

docker image ls
docker run -it -p 5000:80 backend

This will launch the container in interactive mode as if you were logged in on terminal.

The API will be running binding to port 80 of the container, listening to the IP address 0.0.0.0, and will be reachable from the local machine from the address “http://localhost:5000/weatherforecast”.

Summary

Learning Docker takes time and requires an important upfront investment.

It comes with the promise of making code easier to move across machines, being them those used by developers or those used in different environments.

A great article with a lot of use cases for containers may be found here:

https://www.airpair.com/docker/posts/8-proven-real-world-ways-to-use-docker

--

--

Alberto De Natale
Alberto De Natale

Written by Alberto De Natale

Alberto De Natale is a passionate tech-enthusiast software developer.

Responses (1)