Introduction
A buzz word you might have heard these days is containers and how they have many advantages over the traditional Virtual Machines concept we have seen in the past. Without a doubt, containers are a great way to create microservices and have them live in their own space which makes them easy to move and upgrade. Also, deployment to the cloud becomes much efficient with containers as cloud providers like Microsoft Azure provide out of the box solutions for storing and hosting containers. In this article we will look at placing a .NET core Web API application inside a container, hosting the container in an orchestrator which makes the container available for use and finally running and using this containerized application.
The Tools we will be Using
The container technology we will be using is Docker. This has integrated support in Visual Studio 2019, and hence, it is extremely easy to add Docker support to our application both at the time of creation and even after the application has been created. The orchestrator we will be using is Docker Desktop. This is ideal for development and testing.
However, for Enterprise solution hosting, more advanced options like Kubernetes are used. However, once you understand how to use the orchestrator, the knowledge can be applied to all types.
Download and Install Docker Desktop
The first step is to download the latest Docker Desktop version and install it. As I will be working with Windows 10, I have downloaded the version for Windows and installed it.
You can verify the version using the command below:
Creating the Web API Application and Containerizing it
We now proceed to create our ASP.NET Core Web API application in Visual Studio 2019. I am using the Community Edition. We name this application “WebAppDocker”.
We will not select Docker support at the time of creation and add this later. Once the application is created, we will select the below option:
Then select the Windows OS option:
Once the process is completed, a docker file is added to the project. The application is now containerized using docker. Ensure that this looks like the below example:
- #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
-
- #Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
- #For more information, please see https://aka.ms/containercompat
-
- FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-nanoserver-1903 AS base
- WORKDIR /app
- EXPOSE 80
-
- FROM mcr.microsoft.com/dotnet/core/sdk:3.1-nanoserver-1903 AS build
- WORKDIR /src
- COPY ["WebAppDocker/WebAppDocker.csproj", "WebAppDocker/"]
- RUN dotnet restore "WebAppDocker/WebAppDocker.csproj"
- COPY . .
- WORKDIR "/src/WebAppDocker"
- RUN dotnet build "WebAppDocker.csproj" -c Release -o /app/build
-
- FROM build AS publish
- RUN dotnet publish "WebAppDocker.csproj" -c Release -o /app/publish
-
- FROM base AS final
- WORKDIR /app
- COPY --from=publish /app/publish .
- ENTRYPOINT ["dotnet", "WebAppDocker.dll"]
The next step is to add the Container Orchestrator Support. This will create a new project called “docker-compose”. This project will have a file named “docker-compose.yml”.
This file must look like below:
- version: '3.4'
-
- services:
- webappdocker:
- image: webappdocker
- build:
- context: .
- dockerfile: WebAppDocker\Dockerfile
- ports:
- - "8080:80"
This file will be used to launch the containerized application in the Docker Desktop orchestrator. In this file, we see the name of the container is “webappdocker”. It used the docker file created in the previous step. The last thing to note here is that we are routing traffic from port 8080 on the host to port 80 on the container. If we look at the docker file for the application, we see that we expose the web API on port 80 of the container.
We now run the docker-compose project and we will see that the container is now running in Docker Desktop. To verify open the “Docker Desktop” dashboard from the system tray and you will see the below screenshot:
Now to test this Web API running inside the container, let's create another .NET Core console application named “DockerClientApp”. The code for this application is as shown below:
- using System;
- using System.Net.Http;
- using System.Threading.Tasks;
-
- namespace DockerClientApp
- {
- public class Program
- {
- public static async Task Main(string[] args)
- {
- using (var client = new HttpClient())
- {
- var portno = "8080";
- client.BaseAddress = new Uri("http://localhost:" + portno + "/");
- var result = await client.GetAsync("weatherforecast");
- var response = await result.Content.ReadAsStringAsync();
-
- Console.WriteLine(response);
-
- }
-
- }
- }
- }
When we run the application, we can see the below output:
Here, you see that we use port 8080 to call the containerized Web API application, and then this is redirected to port 80 inside the container.
An Unexpected Error
While I was trying to add Docker support, I was getting some strange errors in Visual Studio 2019. After some research, I was able to solve this problem and add Docker support. The solution was as described below:
In the folder,
C:\Windows\System32\drivers
Rename the cbfs6.sys to cbfs6-temp.sys
Then, restart Windows. This should solve the problem and you will then be able to add docker support.
Summary
In this article, we have looked at how to create a containerized ASP.NET Core Web API application and how to host it in the orchestrator Docker Desktop. We then looked at how we can access this application running in a container from another application that was running on the host. As this is a relatively new technology, you might run into numerous issues, especially with deployment and hosting. However, once the setup is complete, it all works very well.