Create and Deploy a Containerized .NET Core App to Azure

Containerization allows us to create flexible, scalable and efficient applications. Generating a containerized .NET Core web app with Docker and Visual Studio is easy. It’s also simple to upload and deploy the resulting container image to Azure. We’re going to do all of the above.

  1. Generate the Application
  2. Upload to Azure Container Registry
  3. Deploy with Azure Container Instances

1. Generate the Application

We’ll need Visual Studio (2019 or later), Docker and the .NET Core SDK (preferably 3.1 or higher) already installed on our machine. Follow these steps to generate a containerized .NET Core application:

  1. Open Visual Studio
  2. Click on Create a new project
  3. Search for and select the ASP.NET Core Web Application template
  4. Click Next
  5. Enter NetCoreDocker in the Project name field
  6. Select Web Application (Model-View-Controller) in the main pane
  7. In the framework version dropdown, ensure ASP.NET Core 3.1 or later is selected
  8. Ensure the checkbox with the label Enable Docker Support is checked
  9. Click Create

Visual Studio has generated a containerized .NET Core web app for us. The most important part of this VS project for containerization is the Dockerfile. While we don’t need to understand its contents for this tutorial, the file is worth inspecting.
Below is an annotated version of the Dockerfile containing a line-by-line Docker-to-english translation:

#Use the .NET Core web application image base 
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
#Set the working directory to /app
WORKDIR /app
# Expose ports 80 and 443 on the container which runs the image
EXPOSE 80
EXPOSE 443
#Use the .NET Core image with the full SDK 
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
#Set the working directory to /src
WORKDIR /src
#Copy the csproj file into the working directory 
COPY ["NetCoreDocker/NetCoreDocker.csproj", "NetCoreDocker/"]
#Restore the nuget packages using the csproj file we copied
RUN dotnet restore "NetCoreDocker/NetCoreDocker.csproj"
#Copy the remaining project files 
COPY . .
#set the working directory to /src/NetCoreDocker 
WORKDIR "/src/NetCoreDocker"
#build the project 
RUN dotnet build "NetCoreDocker.csproj" -c Release -o /app/build
# use the build we just created
FROM build AS publish
#publish the build 
RUN dotnet publish "NetCoreDocker.csproj" -c Release -o /app/publish
#use the first base build 
FROM base AS final
#set the working directory to /app again
WORKDIR /app
# copy the published files into the working directory 
COPY --from=publish app/publish .
# Declare the entry point as the command "dotnet NetCoreDocker.dll"
ENTRYPOINT ["dotnet", "NetCoreDocker.dll"]

Our application has everything we need to build a container image. A container image is a file which contains everything needed to run an application in a container. Our next step will be to build and upload this container image to Azure.

2. Upload to Azure Container Registry

Azure Container Registry(ACR) is a service which lets us store container images in the cloud. It can be easily integrated with many different Azure services including Azure Container Instances, Azure App Service, Azure Functions and Azure Kubernetes Service. We are going to create an Azure Container Registry and upload our container image to it. We will need the Azure CLI installed.

We must create an Azure Resource Group before we can create our container registry. Let’s create a resource group called learn-deploy-acr-rg by running the command below. Feel free to replace EastUS with a closer region.

az group create --name learn-deploy-acr-rg --location EastUS

Next, we will create an Azure Container Registry. The name of a registry must be unique within Azure, so select one accordingly. To create the registry, replace the <registryName> placeholder in the following command and run it:

az acr create ^
    --resource-group learn-deploy-acr-rg ^
    --name <registryName> ^
    --sku Premium

Make a note of the loginServer in the output of the command as it will be needed in the next section. Now, we will build the container image and upload it to ACR. In the command prompt, navigate to the folder which holds the Dockerfile:

cd <pathToFolderWithDockerfile>

Replace the <registryName> placeholder in the below command and run it to build and upload the image to ACR. Make sure to include the .. at the end of the command.

az acr build ^
            --registry <registryName> ^
            --image netcoredocker:v1 ^
            -f Dockerfile ..

Note that in the above command, netcoredocker is the name of our image, and v1 is the tag. Within our registry, a repository called netcoredocker will be created. A repository within ACR contains images of the same name but different tags.

We can verify that our container image was uploaded by replacing the <registryName> placeholder and running the following command:

az acr repository list --name --output table

We should see the name of the uploaded image in the output of the command above.

3. Deploy with Azure Container Instances

Azure Container Instances(ACI) is one of the simplest ways to run a container in the cloud. We simply provide ACI with a container image, and it will create and run a container with that image.

We will use ACI to deploy our dockerized .NET Core web app using the container image we uploaded to ACR. In order to let ACI access the image in ACR, we have to configure some ACR authentication settings. ACR supports both Azure Active Directory authentication and a built-in admin account. For simplicity, we’ll use the latter.

The admin account can be enabled by replacing the <registryName> placeholder and running the following command:

az acr update -n <registryName> --admin-enabled true

To get the credentials for our admin account, replace the <registryName> placeholder and run the following command:

az acr credential show --name <registryName>

Take note of the username and password that appear in the output of the command above.

We can now deploy our app to ACI by replacing the placeholders and running the command below.

az container create ^
    --resource-group learn-deploy-acr-rg ^
    --name dockernetcore ^
    --image <loginserver>/netcoredocker:v1 ^
    --registry-login-server <loginserver> ^
    --ip-address Public ^
    --location EastUS ^
    --registry-username "<username>" ^
    --registry-password "<password>"

The <username> and <password> placeholders should be replaced with the admin credentials we recorded from the output of the previous command.
The <loginServer> placeholders should be replaced with the loginServer value we recorded in section 2.

After waiting for a few minutes, verify the deployment with the following command:

az container show ^
    --resource-group learn-deploy-acr-rg ^
    --name dockernetcore

If our container has finished provisioning, we should see an IP address in the output of the above command. When we paste that IP address into a browser we should see our app loaded. We have successfully deployed our new containerized web app to the cloud.