Deploying ASP.NET Core 2.0 App to Azure using Docker

Problem

How to containerize ASP.NET Core 2.0 web application and deploy to Azure Web App.

Solution

Install Docker.

Create a Docker Hub account (free).

Create Azure subscription (free, gives you credit to play).

Create a simple ASP.NET Core 2.0 web application. Add a file named Dockerfile with following contents:

Note: replace “Fiver.Asp.Docker.Basic” with the name of your solution.

Add another file named docker-compose.yml with following contents:

Note: replace “fiver/basic” with the name you want to give to your image.

My solution looks like this:

Open command line to the root of your project and run below to build and run the application in a container:

Browse the application to ensure it works locally, using URL localhost:8080:

Run the command to create a tag for the image, which is required to upload image to Docker Hub:

Then login to Docker Hub:

Next push the image to Docker Hub:

Once the upload is complete, you’ll see the image in your Docker Hub account:

Go to your Azure account create a new “Web App for Containers”:

Enter details for and select the container:

Once provisioned, you could browse to your application, hosted on Azure, running within a Linux container:

Super cool and easy!

Discussion

Azure provides a highly scalable, configurable and easy to use Platform-as-a-Service (PaaS) environment for our ASP.NET Core web applications. Azure Web App is one of the simplest way to host web applications and the new Web App Container makes it really easy to host Docker containers.

Below I will give a high-level overview of Docker to get you started however, I suggest checking out these resources:

Docker

Docker provides a way to package up your application along with all its dependencies and then deploy as a unit.

First step to achieve this is to create an “Image”, which is a snapshot of everything our application needs to run. I like the analogy Wes Higbee uses, an image as a zip file or an installer that you require to install and run your application. Once you have the image (zip/installer) you could ‘run’ it and this running image in Docker terminology is known as a “Container”.

Images

There are two basic aspects of an image you should be aware of. Images are immutable i.e. once create, an image can’t be modified. You can of course create new images from an existing one and thus images are layered.

For instance, we need .NET Core Runtime to run our application and Microsoft has provided an image that contains all of that in an image called microsoft/aspnetcore. In our solution we took that image as a starting point, then copied our application on top and created a new image.

You could run the docker image ls command to view a list of images on your local machine:

Containers

An image in a running state is known as Container. To run a container you could use the docker run command:

Here --rm means to remove the container when it’s done, -it means to show the interactive window and -p maps the host (your machine) port to containers port:

Configuration Files

Docker has a command line interface (CLI) to manipulate images and containers however there are two configuration files that make things a lot simpler for us:

Dockerfile

This file contain instructions to build an image. We’ve used the following commands in our Dockerfile:

  • FROM: specifies the base image required for our application.
  • WORKDIR: changes the working directory (inside the container) for other commands that follow.
  • COPY: copy files from host (source) to the container (destination).
  • RUN: executes a command inside the container
  • ENTRYPOINT: to configure a container that will run as executable. Here we specify the command to run along with any parameters.

In our solution we are creating our final image in two stages, first we create an image that contains the compiled and published application. For this step we use Microsoft’s image that contain ASP.NET Core build tools. Then we take the published files and create our final image, but this time only utilising Microsoft’s image that contain ASP.NET Core runtime.

The reason I am doing this is to have our final image as small as possible. Note the size of build vs. runtime aspnetcore images in the screenshot above!

Once we have our Dockerfile with instructions to build an image, we run docker build command to create an image:

Here -t specifies the name for our image and . specifies the context for paths specified inside the Dockerfile. In my solution the Dockerfile is in the same path as the application files.

docker-compose.yml

This file contains instructions (among other things) to run containers.  Although you could run a container during docker run command (as shown above), docker-compose.yml file provides an easier solution when you have multiple containers to start.

In this file you declare the services (basically your containers) and the parameters they require to run. You could also specify the settings for building the image i.e. point the compose file to Dockerfile. The benefit of this is that you can build and run containers in one step.

Once we have our compose file, we run docker-compose up command to execute it, as done in our solution. To stop the running services we can run docker-compose down command.

Docker Hub

In order for us to distribute and deploy our images we need to store them in some form of registry. Docker Hub is one options, so is Azure Container Registry. In order to upload images to Docker Hub, you’ll need an account, which is free to setup. Then you could tag your image, login to Docker Hub and push images, like we did in our solution:

Visual Studio 2017 Docker Support

In the above solution I created the files manually, which I would suggest you do to learn the basics, but VS 2017 provides very good support for Docker. Using Docker tools you could debug and deploy your ASP.NET Core applications from within Visual Studio. In my next post I’ll use these tools to create a solution with multiple projects and deploy to Azure.

Source Code

GitHub: https://github.com/TahirNaushad/Fiver.Asp.Docker.Basic

3 comments

      1. Just a couple of ideas as you are writing more tutorials which I think will be helpful to the community. 1. Gulpfile.js and how to concat / minify js files on build. 2. Your thoughts on Angular 2 benefits / disadvantages. (I’ve tried to implement Angular 2 in .NET Core 1.1 last year and it had too many issues to implement for a production application. 3. SignalR 4. Thoughts on powershell script based deployment. 5. Load balancing / cache 6. Azure functions 7. Document DB design architecture for multi-tenant applications. If you need to bounce any ideas, please email me directly.

Leave a Reply