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
- Sass (Scss) instead of CSS
- Node modules
- Sass to CSS conversion using gulp
- ts to js conversion using gulp
- Minification using gulp
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.
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 following software installed in machine.
- Visual Studio 2019 / VS Code
- .NET 5 SDK
- Docker Desktop
- Gulp installed globally (npm install gulp -g)
- VS Code docker extension (not necessary will be good to have)
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
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
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 npm rebuild node-sass –force
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.
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.
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.
Step 3: Prepare a docker file for your project
A sample project containing the docker file can be found here
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.
- 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 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
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.
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
- Hosting containers in your own server
- Through Docker Desktop
- Google Cloud Run
- Azure App Service for containers
- Deploy in Kubernetes Engine – GKE, Azure or AWS
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.