A container journey: .NET 5 web app dockerization

Image by Julius Silver from Pixabay

Create a asp.net core webapp

cd ~
mkdir aspnetcore-webapp
cd aspnetcore-webapp
dotnet new webapp
App opened in VS Code. launch.json is generated later
public static IHostBuilder CreateHostBuilder(string[] args) =>
.ConfigureWebHostDefaults(webBuilder => { webBuilder
.ConfigureAppConfiguration((hostingContext, config) => {
config.AddEnvironmentVariables(prefix: "primebird_");
dotnet publish --configuration Debug
<Some location on your disk>
- aspnetcore-webapp
-- bin
--- Debug
---- net5.0
----- publish
------ wwwroot
------ aspnetcore-webapp.dll
------ aspnetcore-webapp.Views.dll
-- Pages
-- wwwroot
-- Program.cs
-- Startup.cs
dotnet bin/Debug/net5.0/publish/aspnetcore-webapp.dll
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /home/martin/Development/aspnetcore-webapp

Hello Docker

A Docker image consists of read-only layers each of which represents a Dockerfile instruction. The layers are stacked and each one is a delta of the changes from the previous layer.

| Docker | This example | Real world |
| Layer 0 | mcr.microsoft.com/dotnet/aspnet:5.0 | Pizza base |
| Layer 1 | A to be built layer with our app | Tomato sauce |
| Layer 2 | We don't need another layer... | Cheese |
| Layer 3 | We don't need another layer... | Toppings |
For the pizza, prepare the following and put onto the base:
- Chop tomatoes, onion, garlic and basil
- Braise lightly
- ...
touch Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY bin/Debug/net5.0/publish/ app/
ENTRYPOINT dotnet aspnetcore-webapp.dll
docker build -t aspnetcore-webapp .
Sending build context to Docker daemon 10.93MB
Step 1/4 : FROM mcr.microsoft.com/dotnet/aspnet:5.0
---> 5f9a6a778eac
Step 2/4 : COPY bin/Debug/net5.0/publish/ app/
---> c4d100cb93ba
Step 3/4 : WORKDIR /app
---> Running in ced507c950bc
Removing intermediate container ced507c950bc
---> 38e5cb66ac2b
Step 4/4 : ENTRYPOINT dotnet aspnetcore-webapp.dll
---> Running in ffa21d95c08d
Removing intermediate container ffa21d95c08d
---> bf1e224f5191
Successfully built bf1e224f5191
Successfully tagged aspnetcore-webapp:latest
~$ docker image ls | grep aspnet
aspnetcore-webapp latest bf1e224f51 53 sec ago 210MB
mcr.microsoft.com/dotnet/aspnet 5.0 5f9a6af1x9 3 weeks ago 205MB

Do not use this for production purpose!
For your convenience, I’ve uploaded a sample pfx to the projects github repo: https://github.com/martinhorvath/com.primebird.net5webapp

mkdir ~/dockershare
cd ~/dockershare
openssl req -x509 -newkey rsa:4096 -sha256 -keyout devkey.key -out devcert.crt -subj "/CN=dev.local" -days 600openssl pkcs12 -export -name "dev.local" -out devcert.pfx -inkey devkey.key -in devcert.crt
docker run -d -p 5001:5001 --name aspnetwebapp-ct1 -e ASPNETCORE_Kestrel__Certificates__Default__Password=<passwordForTheCertificate> -e ASPNETCORE_Kestrel__Certificates__Default__Path=/opt/webapp/devcert.pfx --mount type=bind,source=<dockersharepath>,target=/opt/webapp aspnetcore-webapp
docker ps -a | grep aspnet
3b3757573b92 aspnetcore-webapp "/bin/sh -c 'dotnet …" 56 seconds ago Up 55 seconds>5001/tcp aspnetwebapp-ct1


docker container logs 3b3757573b92
docker container stop 3b3757573b92
docker container rm 3b3757573b92
docker run -d -p 5001:80 ...same as above



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Martin Horvath

Martin Horvath

I'm a consultant working on international projects in the field of geospatial data and customer experience, with a passion for technology and mountaineering.