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
This tutorial requires the following:
- Basic knowledge of building applications with ASP.NET Core framework.
- .Net Core runtime installed on your computer.
- Docker Desktop installed on your local machine. You can follow Docker’s tutorial for Windows or macOS.
- A Microsoft Azure account.
- A CircleCI account.
- A GitHub account.
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.
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.
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.
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:
Builduses the .NET SDK to install any required dependencies and build the project before publishing it to a folder named
Serveuses the ASP.NET Core runtime image to run the application from the specified working directory, which is
appin 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 .
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
http://localhost:5001/api/weather to review it.
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_USERis the username for the container registry.
DOCKER_PASSis 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.
From the Docker tab, select the image source and its Docker 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: firstname.lastname@example.org 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
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.
Creating environment variables
To fix the credential issue, click the Project Settings button, then click Environment Variables. Add these two new variables:
DOCKER_USERis the username for the container registry
DOCKER_PASSis the password for the container registry.
Click Rerun Workflow from Start.
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:
Note: Please note that your URL on Microsoft Azure should be different from the one showed above.
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.