Dockerize the Application
15 minutesLater on in this workshop, we’re going to deploy our .NET application into a Kubernetes cluster.
But how do we do that?
The first step is to create a Docker image for our application. This is known as
“dockerizing” and application, and the process begins with the creation of a Dockerfile.
But first, let’s define some key terms.
Key Terms
What is Docker?
“Docker provides the ability to package and run an application in a loosely isolated environment called a container. The isolation and security lets you run many containers simultaneously on a given host. Containers are lightweight and contain everything needed to run the application, so you don’t need to rely on what’s installed on the host.”
Source: https://docs.docker.com/get-started/docker-overview/
What is a container?
“Containers are isolated processes for each of your app’s components. Each component …runs in its own isolated environment, completely isolated from everything else on your machine.”
Source: https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-container/
What is a container image?
“A container image is a standardized package that includes all of the files, binaries, libraries, and configurations to run a container.”
Dockerfile
“A Dockerfile is a text-based document that’s used to create a container image. It provides instructions to the image builder on the commands to run, files to copy, startup command, and more.”
Create a Dockerfile
Let’s create a file named Dockerfile in the /home/splunk/workshop/docker-k8s-otel/helloworld directory.
You can use vi or nano to create the file. We will show an example using vi:
Copy and paste the following content into the newly opened file:
Press ‘i’ to enter into insert mode in vi before pasting the text below.
To save your changes in vi, press the
esckey to enter command mode, then type:wq!followed by pressing theenter/returnkey.
What does all this mean? Let’s break it down.
Walking through the Dockerfile
We’ve used a multi-stage Dockerfile for this example, which separates the Docker image creation process into the following stages:
- Base
- Build
- Publish
- Final
While a multi-stage approach is more complex, it allows us to create a lighter-weight runtime image for deployment. We’ll explain the purpose of each of these stages below.
The Base Stage
The base stage defines the user that will
be running the app, the working directory, and exposes
the port that will be used to access the app.
It’s based off of Microsoft’s mcr.microsoft.com/dotnet/aspnet:8.0 image:
Note that the mcr.microsoft.com/dotnet/aspnet:8.0 image includes the .NET runtime only,
rather than the SDK, so is relatively lightweight. It’s based off of the Debian 12 Linux
distribution. You can find more information about the ASP.NET Core Runtime Docker images
in GitHub.
The Build Stage
The next stage of the Dockerfile is the build stage. For this stage, the
mcr.microsoft.com/dotnet/sdk:8.0 image is used, which is also based off of
Debian 12 but includes the full .NET SDK rather than just the runtime.
This stage copies the .csproj file to the build image, and then uses dotnet restore to
download any dependencies used by the application.
It then copies the application code to the build image and
uses dotnet build to build the project and its dependencies into a
set of .dll binaries:
The Publish Stage
The third stage is publish, which is based on build stage image rather than a Microsoft image. In this stage, dotnet publish is used to
package the application and its dependencies for deployment:
The Final Stage
The fourth stage is our final stage, which is based on the base stage image (which is lighter-weight than the build and publish stages). It copies the output from the publish stage image and defines the entry point for our application:
Build a Docker Image
Now that we have the Dockerfile, we can use it to build a Docker image containing
our application:
This tells Docker to build an image using a tag of helloworld:1.0 using the Dockerfile in the current directory.
We can confirm it was created successfully with the following command:
Test the Docker Image
Before proceeding, ensure the application we started before is no longer running on your instance.
We can run our application using the Docker image as follows:
Note: we’ve included the
--network=hostparameter to ensure our Docker container is able to access resources on our instance, which is important later on when we need our application to send data to the collector running on localhost.
Let’s ensure that our Docker container is running:
We can access our application as before:
Congratulations, if you’ve made it this far, you’ve successfully Dockerized a .NET application.