In this tutorial, you will learn how to build a custom ASP.NET Core container with Docker and host the container image on Azure Container Registry (ACR). ACR is a platform owned by Microsoft that allows you to build, store, and manage container images in a private registry.

At the end of this tutorial, you will be able to apply the knowledge gained here to link your container image on the Microsoft Azure registry with a web app service and launch your application. You will learn how to make sure that every new container image built as a result of changes made to your codebase will automatically update the app.

To achieve this, we will:

  • Create a registry to host our container image on Azure Container Registry (ACR) and obtain the access key
  • Create a container image for the project, and build and run the container locally
  • Publish the Docker image to the created Azure Container Registry
  • Create an Azure web app and link it with the published container image
  • Enable continuous deployment and create a configuration file to build and deploy our container image on CircleCI
  • Push the project to GitHub and connect with CircleCI
  • Deploy the container image to the Azure Container Registry

Prerequisites

This tutorial requires the following:

Cloning the demo project

In this section, you will clone the demo project for this tutorial from its repository on GitHub. From the terminal, run:

git clone https://github.com/yemiwebby/docker-dotnet-api.git deploy-dotnet-azure-instance

Once the process is complete, you will have the project downloaded into a deploy-dotnet-azure-instance folder. We will proceed to set up a container registry to host the container image that will be generated for our project.

Creating an Azure Container Registry

The Azure Container Registry stores the image for this project. To create it, go to the Azure portal homepage and click Create a resource. Then select Containers > Container Registry.

Create resource

On the registry creation page, I used the name dockerdotnetcoreapi. You can use any name you want; just remember to use it instead of mine as you follow the tutorial. Next, enter the details required for the registry.

Create container registry

Click Review + Create. You will be redirected to a page where you can review the registry information. Then, click Create to set up a new registry instance.

Getting an access key from the registry

In this section, you will enable Docker access in the Azure Container Registry. This is crucial to the deployment process because it lets you remotely log into the Azure container registry through the CLI and push images to it.

To enable Docker access, open the registry, go to the Settings section and click Access Keys.

This will show you the registry name and login server. Enable the Admin user using the toggle button. Then, copy the username and any of the passwords, preferably the first one. Keep this handy because you will need it later in the tutorial.

Enable Admin and copy access key

Containerizing the application

Next, you will use the custom Dockerfile already included in the cloned project to build a container image. The Dockerfile has the required commands to install all the project’s dependencies, build the project, and run it. Go to the root of the application, open the Dockerfile, and make sure it has this content:

# Build Stage
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY . ./
RUN dotnet restore
RUN dotnet publish -c Release -o out

# Serve Stage
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build /src/out .
ENTRYPOINT [ "dotnet", "docker-dotnet-api.dll" ]

There are two different stages specified in the file above:

  • Build uses the .NET SDK to install any required dependencies and build the project before publishing it to a folder named out.
  • Serve uses the ASP.NET Core runtime image to run the application from the specified working directory, which is app in this case.

This is sometimes called a multi-stage Dockerfile. It combines development and production instructions into a single Dockerfile and reduces complexity in the process.

Building the Docker image

In this section, you will use the registry URL from the previous step to build the Docker image for the project. Run the following command:

docker build -t dockerdotnetcoreapi.azurecr.io/dotnet-api:latest .

Note: Replace dotnetcoreapi.azurecr.io and dotnet-api with the names you chose for the registry URL and login server details.

Based on the content of the application and the Dockerfile, this command will build the container image. Because it uses the registry name and login server you created earlier, it will easily map the container image with the Azure Container Registry.

Running the Docker image locally

Now that you have built the local version of the container image, make sure it works by running the following command:

docker run -d -p 5001:80 dockerdotnetcoreapi.azurecr.io/dotnet-api

This command runs the container in the background, prints the container ID to the terminal, and runs the app on port 5001. Visit http://localhost:5001/api/weather to review it.

App running on Docker locally

Deploying the Docker image to Azure Container Registry

The next step is to log into the Azure Container Registry and push the container image to it. From the terminal, run:

docker login -u DOCKER_USER -p DOCKER_PASS dockerdotnetcoreapi.azurecr.io

If you need to, replace dotnetcoreapi.azurecr.io with your registry URL. Then, replace the following placeholders with appropriate values:

  • DOCKER_USER is the username for the container registry.
  • DOCKER_PASS is the password to the container registry.

After you log in, push the image to the Azure registry by running:

docker push dockerdotnetcoreapi.azurecr.io/dotnet-api:latest

The image will be deployed to the Azure registry.

Creating a web app service for the container

Next, you need to create an Azure Web App and connect it with the container image. Go to the Azure portal homepage and click Create a resource.

Then select Containers > Web App for Containers to create a new web app service instance.

You will be redirected to the Create Web App page. Select an Azure subscription and a resource group. Create a new resource group if you don’t have one. Make sure the default, Docker container, is selected.

Creating web app

From the Docker tab, select the image source and its Docker image.

Select container image

Click Review + Create. You will be redirected to a page where you can review the web app details. Click Create to set up a new Azure web app.

Setting up continuous deployment on Azure

Each time your Docker image is updated, you want the app to receive the update. To make sure this happens, you need to enable continuous deployment for the web app service.

Click the web app name, then go to the Deployment section. Click Deployment Center then scroll down the Settings tab. Turn on continuous deployment by selecting the radio button for it. Click Save.

With continuous deployment selected, the web app will trigger a new deployment of the .NET Core application each time the Docker image is rebuilt on Azure Container Registry.

Automating deployment using CircleCI

Your next step is to add the pipeline configuration for CircleCI. This configuration will automate testing and run the commands to build and push the container image to the Azure Container Registry.

At the root of your project, open the .circleci/config.yml file and update it with this content:

version: 2.1
orbs:
  docker: circleci/docker@2.2.0
jobs:
  build-docker-image:
    executor:
      name: docker/docker
      tag: "3.6"
    steps:
      - checkout
      - docker/install-docker-tools
      - setup_remote_docker:
          docker_layer_caching: true
      - run:
          name: Build and push Docker image
          command: |
            docker build -t dockerdotnetcoreapi.azurecr.io/dotnet-api:latest .
            echo $DOCKER_PASS | docker login dockerdotnetcoreapi.azurecr.io -u $DOCKER_USER --password-stdin
            docker push dockerdotnetcoreapi.azurecr.io/dotnet-api:latest
workflows:
  build-and-deploy:
    jobs:
      - build-docker-image

These scripts pull in the Docker orb from CircleCI. They use its executor to install the tools required for Docker to build and push the image to the Azure Container Registry.

Set up a repository on GitHub and link the project to CircleCI. Review pushing your project to GitHub for instructions.

Connecting with CircleCI

Log into your CircleCI account. If you signed up with your GitHub account, all your repositories will be available on your project’s dashboard. Search for the deploy-dotnet-azure-instance project.

Select project

Click the Set Up Project button. You will be prompted about whether you have already defined the configuration file for CircleCI within your project. Enter the branch name (for the tutorial, we are using main). Click the Set Up Project button to complete the process.

This build will fail because it requires the Azure Container Registry credentials, and you haven’t added them yet.

Build failed

Creating environment variables

To fix the credential issue, click the Project Settings button, then click Environment Variables. Add these two new variables:

  • DOCKER_USER is the username for the container registry
  • DOCKER_PASS is the password for the container registry.

Click Rerun Workflow from Start.

Build successful

Your workflow will run successfully. You can make some changes to the codebase locally and push it to GitHub to further test the continuous deployment process.

That is it!

Go to the URL to review the live app: https://<APPLICATION_NAME>.azurewebsites.net/api/weather.

View App live on Azure

Note: Please note that your URL on Microsoft Azure should be different from the one showed above.

Conclusion

You have just learned how to easily dockerize an ASP.NET Core application, deploy the container image to the Microsoft Azure Container Registry, and launch it on a web service.

With the continuous deployment enabled on the Azure web app, you can be sure that the app will always be updated automatically once you push a new version of the container image to the registry.

I hope that you found this tutorial helpful. Visit this repository for the complete source code of the project.


Oluyemi is a tech enthusiast with a background in Telecommunication Engineering. With a keen interest in solving day-to-day problems encountered by users, he ventured into programming and has since directed his problem solving skills at building software for both web and mobile. A full stack software engineer with a passion for sharing knowledge, Oluyemi has published a good number of technical articles and blog posts on several blogs around the world. Being tech savvy, his hobbies include trying out new programming languages and frameworks.

Read more posts by Olususi Oluyemi