This article will be explaining how to Containerize a .NET 6 Application using Docker. Docker concepts are going to be explained, alongside the most used Docker commands. Also will be explained the importance of the DockerFile and what its content means.
After the theoretical concepts, we are going to a practical step-by-step walkthrough on how to containerize a .NET 6 application. Will be described from the DockerFile creation until this DockerFile is used to create a Docker Image from our application, then we are creating a Docker Container that will be running our .NET 6 Application.
What is a Docker?
Docker is an open-source platform for developing, packing, and running applications. It is extremely fast to set up a Docker Container and deploy a Docker Image, giving the time advantage when needing to manage your environments.
The biggest benefit of docker is that you can package your applications into Docker Images, then run those images in a Docker Container. Your Docker Containers are isolated from one another, meaning that they may have different, or equal, settings, but your Docker Images will always have the same behavior.
Docker Container
A Docker Container works like an isolated Virtual Machine, it has its process isolated from all other processes working on the machine. You can have each container with its own settings, not affecting nor being affected by any other process outside its own environment.
Docker Container main functionalities,
- Can run on any operating system;
- Has its own isolated and independent settings, in a controlled environment.
- Can run on any machine, virtual machine, or a cloud instance.
- May have one or more images running on it.
- Easy to manage, you can create, start, stop, delete or move a container with a few commands.
Container Image
A Docker Container Image is an image used to configure Docker Containers. In this Docker Container Image, you can store the Container configurations, dependencies, binaries, and scripts. If you need to replicate a Docker Container you can easily do this with Docker Container Images.
Docker Image
The Docker Image has all the required tasks needed to package your application. For example, you can restore nugets, download other Docker Images, and build, test, and pack your application.
Benefits of using Containerizing an APP
There are many benefits to containerizing your application but the most important the following sones :
- Fast Deployment, being able to deploy the Docker Image in seconds.
- Consistent Software, always having the same behavior as the Docker Image.
- Platform-independent, can be deployed in any OS and in the Cloud.
- Easy vertical scaling, scaling up and down near real-time.
- Easy horizontal scaling, making use of fewer resources for deployments.
The DockerFile
The Dockerfile is used by Docker to create the Docker Image from your application. The Docker File is composed by some steps needed to be executed in a certain order to create the Docker Image.
Example of DockerFile
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /App
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DockerConsoleApp.dll"]
DockerFile Multi-Stage builds
A Multi-Stage build DockerFile is identified by multiple FROM statements in the DockerFile, whereas each of those FROM statements represents a stage of the build. You can take advantage of a multi-stage build by copying artifacts from one stage to another, and using and reusing artifacts from previous builds.
Our DockerFile is a good example of a Multi-Stage build, and below you can find another example of a multi-stage build.
FROM ubuntu AS base
RUN echo "base"
FROM base AS stage1
RUN echo "stage1"
FROM base AS stage2
RUN echo "stage2"
Essential commands
Docker has many different commands that create, manage, and interact with containers and images. These Docker commands are essential to managing your containers:
- Docker build, building the Dockerfile.
- Docker run, set a container for the image, and then starts this image.
- Docker ps, list the containers.
- Docker stop, stop one or more running containers.
- Docker rm, remove one or more containers.
- Docker rmi, remove one or more images.
- Docker image, manages a Docker Image.
Implementation Step by Step
Pre Requisites
Create the Console Application
Create an empty console application using .NET 6. Name it as "DockerConsoleApp" and change your Program.cs to the following:
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
Console.WriteLine(DateTime.Now.ToLongDateString());
Console.WriteLine("App closing in 10s");
Console.WriteLine("10");
await Task.Delay(1000);
Console.WriteLine("9");
await Task.Delay(1000);
Console.WriteLine("8");
await Task.Delay(1000);
Console.WriteLine("7");
await Task.Delay(1000);
Console.WriteLine("6");
await Task.Delay(1000);
Console.WriteLine("5");
await Task.Delay(1000);
Console.WriteLine("4");
await Task.Delay(1000);
Console.WriteLine("3");
await Task.Delay(1000);
Console.WriteLine("2");
await Task.Delay(1000);
Console.WriteLine("1");
await Task.Delay(1000);
Create the DockerFile
Create the following DockerFile at the same level as your .csproj file:
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /App
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DockerConsoleApp.dll"]
Open a Command Prompt
Now we are executing the following Docker commands to create and run our application:
Change to the folder where you have your DockerFile
Run the Docker build command, passing the image name to be created. You can notice that all the steps in the DockerFile will be executed respecting its order.
build -t sample-thiago-image -f Dockerfile .
Validate if we have this new image in our Docker Images.
Docker images
Now we have to create a Docker Container to run the Docker Image. The output will be the Docker Container ID.
docker create --name sample-thiago-container sample-thiago-image
Now we can see the Docker Container from the Docker Desktop
If we start this Docker Container we have the desired output as follows:
Congratulations! You have successfully containerized a .NET 6 APP using Docker.
External References