How to create a docker image for containerizing an ASP.NET Core MVC 5.0 Web Application
By: Bharat Dwarkani
Tags: Aspnetcore, DevOps, Docker, Web Development, Dotnet Core

Docker — ASP.NET Core

In this tutorial, you will be learning about how to dockerize an ASP.NET Core MVC 5.0 web application to build a docker image for a production build.

Normally, you may find several articles on dockerizing simple ASP.NET Core projects. Even if you try to use a Visual Studio feature for adding docker support to a project, it will generate a simple docker file which may not work if you have a complex project structure. In this article, I will explain using a docker file that can be used for a production build.

What is the need for Dockerization?

You may think, why do I need to dockerize, if I can just host my project in Windows IIS, Azure Web App, or in Linux VM. You may be right if you are just running a personal project or a small project for a single company. But for running a scalable product for a large scale enterprise or a high traffic website dockerization would benefit you. I will list some of the benefits of dockerization.

Benefits of Dockerization

Building scalable apps

Reduction in cost by running apps in containers

Reduction in infrastructure and system resources for running multiple instances

Easy distribution of apps to customers

Running apps in Kubernetes

Running apps in Azure Web app for containers, Google Cloud Run

Technologies used in sample ASP.NET Core project

In this tutorial, the ASP.NET Core MVC project used for dockerizing uses the following technologies:

Separate .NET Standard class library project as a dependency

TypeScript

Sass (Scss) instead of CSS

Node modules

Sass to CSS conversion using gulp

ts to js conversion using gulp

Minification using gulp

Webpack

Basically a project setup similar to how your production-grade real-time project would look like. In this post, I have demonstrated using an ASP.NET Core MVC project, dockerizing an ASP.NET Web API project is much simpler. You can remove the node and gulp related codes from the docker file.

Prerequisite

In this sample, I will be explaining using a Windows machine, building a Linux docker image. You may even use a Linux machine.

This tutorial requires that you have basic knowledge of working with ASP.NET Core.

Ensure you have the following software installed on the machine.

Steps for Dockerizing ASP.NET Core app

Step 1: Clone a sample project from GitHub

You can find a complete working project hosted on my GitHub repo

https://github.com/bharatdwarkani/asp-net-core-mvc-docker-sample

Check out the Microsoft guide if you want to create a new project.

Step 2: Building a project using Visual Studio

Build a project in Visual Studio 2019 latest version supporting .NET 5. This step is just to ensure that project builds and runs locally without any issues.

Once successful, you will see this page in the browser

Sample web app

Troubleshooting steps if you face an error while running a project in Visual Studio

Node SaaS binding issue

If you face an error as shown in the screenshot below, then open your project folder in windows explorer. Run this command in cmd prompt rebuild node-sass -force

Node Saas binding issue

Ensure task runner explorer loads gulp tasks

This project uses gulpfile to build client-side dependencies and minification, so ensure this is loaded. If tasks are not listed, hit the refresh button. Make sure gulp is installed at the global level (npm install gulp -g) if you face an error even after refresh. Cross-check, npm packages are installed in the project.

Task Runner Explorer for Gulp

Prebuild Events

Gulp build is triggered using an MS pre-build event. For switching debug/release mode in webpack configuration file, the node environment variable is used. Environment configuration is also used in the gulp file.

MS Build Prebuild event

If npm packages (node_modules) are not installed automatically in your project, ensure that settings are enabled in visual studio to install the missing package on the build.

NPM restore settings

Step 3: Prepare a docker file for your project

A sample project containing the docker file can be found here

https://github.com/bharatdwarkani/asp-net-core-mvc-docker-sample/blob/master/Dockerfile

Some tips for dockerizing

It is good to use mcr.microsoft.com/dotnet/core/aspnet:5.0- alpine Linux image as a base since it will create small size images. At the time of writing this article, the alpine image was not available for .NET 5.

Linux image as a base since it will create small size images. At the time of writing this article, the alpine image was not available for .NET 5. To utilize caching, the docker file used here uses a multi-stage build feature of docker. This will speed up the subsequent build process.

The environment variable passed in the docker file overrides the configuration value used in the appsettings.json file.

ENV AppSettings__EnableHTTPS=”false”.

Secret credentials/settings are better to use through the environment variables rather than hardcoding in code or app settings. So that you don’t have to build separate images for dev, staging, and production.

Use the .dockerignore file to skip unwanted folder copying in the image. This will reduce the size of the image and build speed.

Some Best practices for building containers by google.

Never include secret credentials in your container images.

Scan images for vulnerabilities, there are various tools available, some cloud vendors offer vulnerability scanning feature in built-in their container registry service.

Step 4: Building a docker image

Make sure Docker Desktop (Linux) mode is up and running. I am going to use the VS Code for building images.

Open a folder in VS Code.

Type this command in the terminal to build a docker image.

docker build -t sample-app .

sample-app is the image tag name. After a few minutes, docker image will be built and ensure it is success

Building Docker file

Step 5: Running a docker image

To run a docker image, run this command

docker run -p 8080:80 sample-app

sample-app — image name built-in last step

8080 — is the actual port exposed outside

Open this URL in browser http://localhost:8080

If you see this page, then you have successfully containerized your app.

Dockerized source web page

Some more useful docker commands checkout Docker cheat sheet

Container Registries for Docker

If you want to distribute your app or use it in K8s. You can push your application image to central container registries. There is an option to make images public/private. I would recommend setting permission as private for apps that are not going to be distributed to the public.

Running your image in Cloud

There are various ways you can run your containers, some of them are listed below

Conclusion

I hope, this article helped you in dockerizing an ASP.NET Core MVC app for running in production. In my next post, I will explain how to publish this docker image in Google Kubernetes Engine.