Making an ASP.NET core application and docker work together

If you are looking for a basic way to understand and use these two technologies, this is a starting point. What ASP.NET Core is? What can I do with ASP.NET CORE? What is Docker and how can I use it together with ASP.NET Core applications? These are the questions I’ll try to explain with some examples, so enjoy reading and most of all, enjoy coding.

First of all, we need to install a few things to make this tutorial work:

  • Install .NET CORE platform. The link will lead you to the download page and if you are a new user, it will guide you through the installation process
  • Install a code editor. I use Visual Studio Code, but you can install Atom, or Visual Studio or any one you like
  • Download and install Docker
  • You will need Windows 10 Pro or above in order for this tutorial to work.

ASP.Net Core

ASP.NET Core it’s an open source development framework maintained by Microsoft and the .NET community on GitHub. It’s cross-platform, that means that it will work on Windows or macOS or Linux operating systems.

You can build web cloud-based applications, web applications and services, IoT apps and mobile backends and more.

The great benefit for my point of view is that it’s cross-platform, so your applications will run in any of the operating systems I named above. Another advantage is that your applications can run on .NET Core or even .NET Framework. You can deploy your applications to the cloud or on-premise too, and you can use your favorite development tools to create new software.

You can read more about ASP.NET Core here.

Download the installer from the previous link, and follow the installation process. If succeeded, you should see something like this at the end of the installation process:

Image of the installation process of Microsoft .NET core SDK

To check if everything is correctly installed, you can run this on your command line:

dotnet
Result of the dotnet command

Then we can try to create a console application. We do this to check if the command line options are working properly. You can execute this command to do so:

dotnet new console
result of the new console dotnet command

We’ll go back to ASP.NET soon, but for now, we will install the next tool.

Docker

Docker it’s a new way of virtualization. Instead of virtualizing a hole operating system (like VitualBox or VmWare applications do), you only virtualize the environment needed for your application to run.

It uses the kernel of your actual operating system (the one is running on your computer) that is why uses less resources than a virtual machine (from now on I will call these a VM) and gives you the possibility to create a sandbox environment that allows you to develop, run and debug your applications.

A VM it’s a hole operating system that runs in a virtual hardware powered by your installed OS called the host. This isolation comes with a great cost of resources of the host in terms of computing operations. Docker instead, uses a new concept called container.

VM architecture

A container it’s, as the official Docker documentation says, a

“…standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings…”

Docker architecture

Benefits?

This new concept allows you to deploy your application easily regardless of whether the target environment is a private data center or a cloud or even your personal computer or laptop. Its gives you a predictable and isolated environment where to run your applications and for your fellows’ developers too because it assures you that your application will run the same for them as for you.

Apart from portability containers also give more granular control over resources giving your infrastructure improved efficiency which can result in better utilization of your computer resources.

So let’s install it! but first a few considerations…

Before the installation, please carefully review the requirements to install Docker. I did it on a Windows machine, and a Windows Professional license is required. You can’t do it with a home license. This is because Docker needs the Hyper-V feature activated (don’t worry, during the installation Docker will activate it for you). Hyper-V is the Microsoft competitor for VirtualBox or VMWare, it’s a software that allows you to create virtual machines. If you want to read more you can do it here. For this guide, you only need to know that it has to be activated if you are in a Windows environment.

If everything went fine, you should see something like this:

Docker configuration settings. First step of the installation process
Installation succeeded message

After de installation, the OS will restart and Docker will ask you to activate Hyper-V. Please have in mind that Hyper-V and VirtualBox (or VMWare) VMs can’t work together. This is very important because if you have VMs previously created with VirtualBox or VMWare they won’t work again. You can read more about this here. There are some blogs in the web that supposedly help you to have both working. I didn’t test those solutions, but if you are in this scenario, it’s an starting point.

Another thing that I’ve tested with no luck was a virtualized scenario. I used a VirtualBox VM, installed Windows on it and then tried to configure the environment there but docker didn’t start. Trying to solve it I did some research in the web and finally I found this article that tells you that docker doesn’t work properly in nested virtualization scenarios so, I decided to install it in my personal laptop (previous a recovery point that I’ve created 😉… just in case).

Docker is a client-server architecture. It has a client a host (it’s a daemon that could run in your laptop or in another server) and the docker registry (this is the place where the docker images run).

Docier client-server architecture

The client name is docker and you have access to it through the command window on Windows or using a power shell.

Docker command will allow you to interact with dockerd. Running the commands, you can check if docker is running, the containers and images that are running, etc. The commands are listed here and you have full help of how to use them and what they do so I won’t extend on this topic. The common ones you will need are the following:

docker container ls to list all the containers that are currently running

As you can see, here you have important information like the container id, or the name of the image that is running in that container and the imaginary Name docker gave it (in the Names column).

docker images to see which images are running

docker build to create an image

docker run to run the image you created for your application

The dockerd it’s the name of the daemon that it’s a persistent process that manages containers. You can check it on the local services running on the machine.

A registry is a place where the docker images are stored. There is a public registry that anyone can use called Docker Hub and this is the registry configured by default. When you use commands like docker pull or docker run the required images are pulled from the configured registry. You can have your own private registry too.

In the images below, you can see the docker images existing in the hub for ASP.Net Core

As Dockers Site says an Image is a read-only template with instructions for creating a Docker container. You can create your own images or use those that are public and registered in a registry.

Working together

As I previously told you my favorite code editor is Visual Studio Code because it’s free, it has a lot of extensions made for other developers that help you to improve the coding experience and it’s lightweight. To making this tutorial, I’ve downloaded two extensions one for C# and the other for Docker.

Click in the Extension button and then write c#, look for the one you see in the picture below and press the install. Do the same for the Docker extension.

One of the things that comes with Visual Studio Code (from now on VS Code) is that it has the terminal integrated so is easier to execute commands inside it so you don’t need to go on switching between screens. Just go to the Terminal menu and select New Terminal.

We are going to create an application that will be very simple, it will have a restful service that will return an array of data this is what we call a WepApi. If you want to learn more, you can start with the following tutorial online. Usually, a WebApi es one of the members of a bigger application that can contain a website that will use the data returned by the WebApi, but that is a matter of another blog. For now, I’m going to keep it simple.

Go to the folder where you want to create the application and type the next on a command window to create the folder of the application

mkdir AspNetDocker

Then type the next to create the application

dotnet new webapi -o AspNetDocker

Then we will open the application in a new VS Code window with the next command

code AspNetDocker

A notification message will tell you that some files were missing for build and debugging of the application, press yes.

A new folder was added to the solution is the vscode folder.

This application in its folder Controller, has a file called ValuesController.cs. This is a class file that has the code of our little service. In the code below, it is defined the action that will be executed for a Get request of our Api.

// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { “value1”, “value2” };
}

At this point we will add a Dockerfile. This file is a configuration file that tells docker which commands are necessary to execute on the command line to assemble an image. Remember that an image is a pre-built environment for a certain technology or service, an image is a collection of files, libraries and configuration files that build up an environment. Because writing a dockerfile from the scratch it’s a little bit tricky, here is when our VS Code Docker extension will help us to do it for our application.

Type the following in the command palette (ctrl + p) of VS Code:

>Docker: Add Docker Files to Workspace

It will ask you which is the application platform please select ASP.NET Core

Then it will ask you to select the operating system, select please Windows

Next introduce the port where our application will be listening the requests and press ENTER. I’ve used the port 80

All this will add for us two files, Dockerfile and dockerignore. The dockerignore file has the main function of exclude files not relevant to the build. It helps to avoid sending unnecessary, large or sensitive files and directories to the daemon and potentially adding them to images. You can read more about this file in dockers site.

The first three lines the FROM keyword tells docker that the Base Image of our application will be microsoft/dotnet:2.2-aspnetcore-runtime-nanoserver-1709. Then it sets the working directory (WORKDIR) and calls it /appAspNetDocker. If this directory doesn’t exist, it will create it. Then the EXPOSE keyword tells docker that the container is listening on the specified network port.

FROM microsoft/dotnet:2.2-aspnetcore-runtime-nanoserver-1709 AS base
WORKDIR /appAspNetDocker
EXPOSE 80

The next block of instructions will build our application, it means it will generate all the necessary files for our application to work and will leave it in the specified workind directory, in this case /src.

FROM microsoft/dotnet:2.2-sdk-nanoserver-1709 AS build
WORKDIR /src
COPY [“AspNetDocker.csproj”, “./”]
RUN dotnet restore “./AspNetDocker.csproj”
COPY . .
WORKDIR “/src/.”
RUN dotnet build “AspNetDocker.csproj” -c Release -o /appAspNetDocker

Then it will publish the result of the previous block of instruction into the /appAspNetDocker directory

FROM build AS publish
RUN dotnet publish “AspNetDocker.csproj” -c Release -o /appAspNetDocker

And finally, the last block of instructions tells docker that using what was configured in the base block, copy the result of the publish block into the working directory and configure our container to run as an executable (please refer to the ENTRYPOINT keyword).

FROM base AS final
WORKDIR /appAspNetDocker
COPY — from=publish /appAspNetDocker .
ENTRYPOINT [“dotnet”, “AspNetDocker.dll”]

In order to run our container, first we have to create an image. In a VS Code terminal, write and execute the following instruction

docker build -t aspnetdkrimage .

The first step will take a long time the first time you execute this instruction because docker has to download the entire base image from the hub repository.

Let list the images that are currently running:

docker images

And here is our newly image cheers!

Now we will run our container and we will check if our application is returning the values sets by default in the controller:

docker run -d -p 8090:80  aspnetdkrimage

Now we list the running containers

docker run -d -p 8090:80  aspnetdkrimage

And finally, we navigate to our application to test if the little service is returning data. Write the following in your internet browser

The application running in docker

The end?

No, this is just the beginning.

In this git repository I’m leaving you an ASP.NET Core webapplication that it’s a basic (really basic) book store. With this application you can create Books, list them, edit their information or delete them. Even you can send the list of books through email. Because I’m new with these technologies, I’ve used this Microsoft tutorial to create the application and this blog to learn how to send emails using a google account.

This application uses Entity Framework to create a local db and seed it.

What I want you to do as a final exercise, download the code from the git link, change the section Email in the appsettings.json (put a valid Gmail account and password — activate Less secure app access or you will receive an error when trying to send the email). Then, create a docker image using the dockerfile that is in the solution and run the application.

This is just a starting point so keep learning and keep coding!

Thanks for reading!

Links that helped me