Write Dockerfile for traditional ASP.NET Apps (Part 1)
Ali Heydari
⏳ 8 min read
Introduction
I was working on a project that was using traditional ASP.NET.
The project was using a lot of third-party and In-house libraries/projects and it was a bit hard to maintain.
I decided to containerize the application and use Docker to run it.
The project had 3 main applications:
Web Application (ASP.NET MVC)
Web API (ASP.NET Web API)
Windows Service (Console Application)
It had a few other projects that were used by the main applications.
Write Dockerfile
I decided to use a multi-stage Dockerfile to build the application.
The first stage is to build the application and the second stage is to run the application.
Web Application (ASP.NET MVC)
As I mentioned, the project contains a Web Application (ASP.NET MVC), A Web API (ASP.NET Web API) and a Windows Service (Console Application).
In this article, I will explain how to write a Dockerfile for the Web Application (ASP.NET MVC).
Step 1: Write builder stage
The first stage is to build the Web Application and Web API.
I used the mcr.microsoft.com/dotnet/framework/sdk:4.8 image to build the application.
Define the working directory and all needed arguments like credentials and build configuration.
Copy the solution file to the working directory.
Copy the packages.config and .csproj files to the working directory. before installing dependencies.
This will help Docker to cache the dependencies and speed up the build process.
(Optional) In that project I had to install the NuGet packages from a private repository. So I disabled the default NuGet repository and added the private repository.
If you don't have a private repository, you can skip this step.
Install the NuGet packages. you can combine this step with the previous step if you have a private repository to reduce the number of layers.
Copy the rest of the files to the working directory.
Let's cook!👨🍳 Build the project using MSBuild. (msbuild.exe is already installed in the base image)
Boom! We have a build! Now let's create the runtime image.
Step 2: Write runner stage
I used the mcr.microsoft.com/dotnet/framework/runtime:4.8-20220712-windowsservercore-ltsc2019 image as the base image for the runtime image.
In a Dockerfile, SHELL is an instruction that sets the default shell used for subsequent instructions.
In this case, it sets the default shell to PowerShell and passes two arguments to it: $ErrorActionPreference = 'Stop' and $ProgressPreference = 'SilentlyContinue'.
$ErrorActionPreference is a preference variable that determines how PowerShell responds to non-terminating errors.
Setting it to 'Stop' means that PowerShell will treat non-terminating errors as terminating errors, which will cause the script to stop running.
$ProgressPreference is another preference variable that determines how PowerShell displays progress information.
Setting it to 'SilentlyContinue' means that PowerShell will suppress all progress information.
Install the necessary Windows features, remove existing files, download ServiceMonitor.exe, and update the .NET Native Image Generator (NGEN)
(Optional) Install the URL Rewrite module. I needed this module to rewrite the URLs in the web.config file. So if you don't need it, you can skip this step.
I used Chocolatey to install the module.
If you don't like to install using Chocolatey, you can use the following command to download and install the module.
Set aspnet_state service to start automatically and allow remote connections. I needed this service to store session state in a SQL Server database.
Update SHELL to use PowerShell and pass only one argument to it: $ErrorActionPreference = 'Stop'.
Set the working directory to C:\inetpub\wwwroot.
Copy the build output from the builder image to the working directory.
Remove the default website and create a new website and application that listens on port 80.
Define the entry point for the container. The entry point is the command that is executed when the container starts.
In this case, the entry point is ServiceMonitor.exe,
which is an entrypoint process for running IIS in Windows containers.
Tada! We have a runtime image! Now let's create the final image.
The entire Dockerfile looks like this:
Build Dockerfile
First for building this images and running the container you need to have Docker installed on your machine if you don't have it you can download it from here.
Second you need to switch to Windows containers by right clicking on the Docker icon in the system tray and select Switch to Windows containers.
Now you only need to build your Dockerfile and tag it with a name. Here is the command to build the Dockerfile:
Run the container
Now you can run the container using the following command:
Test the container
Now you can test the container by navigating to http://localhost:8080 in your browser.
You are done! I hope you enjoyed this tutorial. If you have any questions or comments please feel free to contact me.