Running .NET inside Docker - Deploying ASP.NET Core as a Docker Container

In this blog post, you'll learn how to deploy an ASP.NET Core application with .NET Core as a Docker Container.

Docker is an open-source project to easily create lightweight, portable, self-sufficient containers from any application. The same container that a developer builds and tests on a laptop can run at scale, in production, on VMs, bare metal, OpenStack clusters, public clouds and more.

Step 1 - Example Application

Configured your ASP.NET Core to listen on port 5000:

 var host = new WebHostBuilder()
                .UseConfiguration(config)
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseUrls("http://0.0.0.0:5000")
                .UseIISIntegration()
                .UseStartup()
                .Build();

            host.Run();

Step 2 - Dockerfile - Base Image

To run an application inside of a container you first need to build the Docker Image. The Docker Image should contain everything required to start your application, including dependencies and configuration.

Docker Images are created based on a Dockerfile. A Dockerfile is a list of instructions that define how to build and start your application. During the build phase, these instructions are executed. The Dockerfile allows image creation to be automated, repeatable and consistent.

The first part of a Dockerfile is to define the base image. Docker has an embrace and extends approach. Your Dockerfile should only describe the steps required for your application. All runtime dependencies, such as .NET Core, should be in the base image. The use of base images improves the build time and allows the image to be shared across multiple projects.

In this case, the base image is the official Microsoft DotNet Image. The image has .NET Core runtime and tooling configured. Everything our approach needs.

Start writing the Dockerfile by defining the base image.

FROM microsoft/dotnet:1.0.0-preview2-sdk

Step 3 - Dockerfile - Dependencies

The next stage of the Dockerfile is to define the dependencies the application requires to start.

The RUN instruction executes the command, similar to launching it from the bash command line. The WORKDIR instruction defines the working directory where commands should be executed from. The COPY instruction copies files and directories from the build directory into the container image. This is used to copy the source code into the image, allowing the build to take place inside the image itself.

All the commands are run in order. Under the covers, Docker is starting the container, running the commands, and then saving the image for the next command.

Continue creating the Dockerfile by defining the directory and how to download and configure the dependencies.

RUN mkdir /app
WORKDIR /app

COPY project.json /app
RUN ["dotnet", "restore"]

To deploy the ASP.NET Core application we need to create a directory for our application and set it as our working directory. The next stage is to define the dependencies of our application, defined in the project.json file. We copy this file into the /app directory. Once copied we can run dotnet restore to download the required packages.

Step 4 - Dockerfile - Application

Once the Dockerfile has the required dependencies it now needs to define how to build and run your application.

The EXPOSE instruction is a description about what ports the application is listening on. This helps describe how the application should be started and run in production. This can be considered part of the documentation, or metadata, about the image and application.

The CMD instruction defines the default command to run when the Docker Container is started. This can be overridden when starting the container.

Continue creating the Dockerfile by defining the directory and how to download and configure the dependencies.

The first stage is to build the DotNet application.

COPY . /app
RUN ["dotnet", "build"]

The second stage defines how the application starts and the ports it's running on.

EXPOSE 5000/tcp
CMD ["dotnet", "run"]

Step 5 - Build

With the Dockerfile created, you can use the Docker CLI to build the image.
Create a Docker Image by building and executing the Dockerfile using the Docker CLI.
When creating the image we also define a friendly name and tag. The name should refer to the application, in this case aspnet. The tag is a string and commonly used as a version number, in this case it's v0.1.

docker build -t aspnet-app:v0.1 .

You can view the Docker Images on your host using

docker images | head -n2

Try breaking the build and see what happens.

Step 6 - Run

Once the Docker Image has been built you can be launch it in the same way as other Docker Images. Start the newly build image and expose the port 5000 so the web application can be accessed.

docker run -d \
  -t -p 5000:5000 \
  --name app \
  aspnet-app:v0.1

Once the container and process has started you can use curl to access the running application. You can view the application logs using

docker logs app
curl http://docker:5000

You've now successfully built a .NET application as a Docker Image.

Maher Jendoubi

Speaker, Microsoft MVP, Blogger, Pluralsight Paris Study Group Leader.

Subscribe to Hi! I'm Maher.

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!
Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.