Deploy an ASP.NET Core Application on Linux with Docker

Docker and containerization is all the rage these days. Adoption in the .NET community has been slow so far, but that’s changing. With the introduction of cross-platform .NET Core, it became much easier to run .NET code on Linux machines. And, since Docker is a primarily Linux-based technology, it’s now very straightforward to deploy ASP.NET Core applications using Docker. How? Let’s take a look.


At a high level, containerization solves problems related to deploying and running your application on a server somewhere “out there.” I have fond memories of deploying code for the first time as a junior developer by manually copy-pasting binaries into production. Fortunately, no one is doing that anymore (right?). Today, automated build tools can handle the steps required to push code to a production machine. Containerization can take you one step further… by abstracting away the machine itself.

How does Docker work?

Docker is similar to a virtual machine, but without the overhead. A service called Docker Engine runs on your server, ready to host one (or many) containers. Containers that run on top of Docker Engine are completely isolated. As far as the applications inside each container are concerned, they’re running on separate machines. In reality, they’re just isolated processes on the same machine.
Containers run Docker images, which are packages that represent everything needed to spin up your application or service inside the container: dependencies, shared libraries, application binaries, and so on. During development, you define the “recipe” that is built into the final image. This recipe is called a Dockerfile.

Why use Docker instead of a virtual machine?

If you’ve ever set up a web or application server, think of everything necessary to go from a “bare metal” virtual machine to a running production server: besides installing the OS, you have to get the latest patches, install framework runtimes and dependencies, grab third-party libraries, configure networking and routes to your other services, install your application code, and then configure it all. And, if you have multiple servers in your environment, or you’re frequently spinning up new servers, you have to do this a lot.
Containerization allows you to do all of the setup work once, and build the result into an image you can immediately run on any machine using Docker Engine. It moves the focus away from setting up servers, and lets you instead focus on building images that include everything needed to run anywhere.

  • Containerization doesn’t replace virtual machines – in fact, the two technologies go hand-in-hand. A common approach is to have a handful of virtual machines in a cluster, each running Docker Engine and hosting many containers.

Ultimately, there are use cases for both technologies. You probably don’t need to boot up an entire guest OS and tens or hundreds of background services just to run a single application – running inside a thin container makes more sense. Conversely, sometimes you do want to have an entire OS dedicated to a particular task, especially if it’s something CPU-intensive. Virtual machines are well-suited for the latter, and containerization makes the former easier to manage.
If you’ve never set up Docker or deployed an ASP.NET Core project as a Docker image, this is the tutorial for you! I’ll walk through the steps required to:

Setting up Docker

It’s easy to get started with Docker. First, you have to install the Docker Engine on your machine (or your server)
For my own testing, I installed Docker for Windows on my Windows 10 development environment, and also on my Mac. To make sure the service is installed correctly, run this from the terminal:

> docker --version
Docker version 1.12.0-rc4, build e4a0dbc, experimental

If you see a version number, everything is working!

Creating an ASP.NET Core project

If you don’t already have the latest .NET Core tooling installed, grab that at the official .NET Core site. Once it’s installed on your machine, you can create a new directory and scaffold a new ASP.NET Core project easily

mkdir AspNetCoreHelloWorld
cd AspNetCoreHelloWorld
dotnet new -t web

To make sure everything is working, try running the project locally first:

dotnet restore
dotnet run

Building a Dockerfile for ASP.NET Core

Docker needs a Dockerfile that contains the “recipe” for creating an image based on the project. Create a new file called Dockerfile in the project directory:

touch Dockerfile

On Windows, you can run notepad Dockerfile instead, or use your favorite text editor. Make sure that this file isn’t saved with an extension like .txt – it’s supposed to have no extension.
The Dockerfile contents are straightforward:

FROM microsoft/dotnet:latest
COPY . /app
RUN ["dotnet", "restore"]
RUN ["dotnet", "build"]
EXPOSE 5000/tcp
ENTRYPOINT ["dotnet", "run"]

Here’s what each of these instructions does:

  • FROM tells Docker that you want to base your image on the existing image called microsoft/dotnet:latest. This image already contains all the dependencies for running .NET Core on Linux, so you don’t have to worry about setting those up.
  • COPY and WORKDIR copy the current directory’s contents into a new directory inside the container called /app, and set that to the the working directory for the subsequent instructions.
  • RUN executes dotnet restore and dotnet build, which restores the packages needed to run the ASP.NET Core application and compiles the project.
  • EXPOSE tells Docker to expose port 5000 (the default port for ASP.NET) on the container.
  • ENV sets the environment variable ASPNETCORE_URLS in the container. This will ensure that ASP.NET Core binds to the correct port and address.
  • ENTRYPOINT specifies the command to execute when the container starts up. In this case, it’s dotnet run.

Creating the Docker image

Once you’ve created the Dockerfile, you’re ready to build an image:

docker build -t mydemos:aspnetcorehelloworld .   
docker build -t mydemos:aspnetcorehelloworld .

See that trailing period? That tells docker to look in the current directory for a Dockerfile. The -t flag tags the image with tag mydemos:aspnetcorehelloworld.
When the image finishes building, you can spin it up:

docker run -d -p 8080:5000 -t mydemos:aspnetcorehelloworld
docker run -d -p 8080:5000 -t mydemos:aspnetcorehelloworld

The -d flag tells Docker to run the container in detached mode (in the background). The -p flag will map port 8080 on the host machine to port 5000 inside the container. Finally, the -t flag is used to specify which image to run. That’s it! You should see your container running when you check docker ps

Best ASP.NET Hosting Recommendation provides its customers with Plesk Panel, one of the most popular and stable control panels for Windows hosting, as free. You could also see the latest .NET framework, a crazy amount of functionality as well as Large disk space, bandwidth, MSSQL databases and more. All those give people the convenience to build up a powerful site in Windows server. offers ASP.NET hosting starts from $1/month only. They also guarantees 30 days money back and guarantee 99.9% uptime. If you need a reliable affordable ASP.NET Hosting, should be your best choice.