CI/CD using Azure DevOps to run Dot Net Core Based Docker Containers

Recently I started exploring Pipelines in Azure DevOps (previously VSTS) to build a Continuous Integration and Continuous Deployment process. The main idea was to trigger an automated Build and Release for an application which would then run inside a Docker Container in Azure. The following setup was used in the process:

  • ASP.NET Core Web API
  • GitHub
  • Azure Container Registry: To store Docker Images inside a Repository
  • Web App for Container: To run the Docker Image as an App Service
  • Azure Pipelines: Setup Automated Build & Release

An Azure subscription is required for using Container Registry and AppService and an Azure DevOps account is required for Azure Pipelines.

Web App for Containers allow you to run App Service on Linux natively, thus enabling you to run Dot Net Core applications inside a Linux Container. This is an important factor, as when building Docker Images for Dot Net Core the underlying platform contributes to the size of your Docker Image. A windows environment based Docker Image typically has a higher memory footprint than a Linux based image.

Setting up Azure Services

We start off by creating a Container Registry in Azure which will later be used in Build Pipeline.

Creating your Dockerfile

Next we create the Dockerfile for the ASP.NET Core Application. I have used multi stage build which allows us to create smaller images using caching and layers.

FROM microsoft/dotnet:sdk AS build
WORKDIR /app

COPY *.csproj ./
RUN dotnet restore

COPY . ./
RUN dotnet publish -c Release -o publishdir

FROM microsoft/dotnet:aspnetcore-runtime AS runtime
EXPOSE 5555
WORKDIR /app
COPY --from=build /app/publishdir .
ENTRYPOINT ["dotnet", "WebAppContainer.dll"]

Writing Build Pipeline in Azure DevOps

The Web API project is hosted in GitHub and hence we choose GitHub as source and connect to the repository for which we want to setup the build. Azure DevOps would require an authorization with the GitHub account.

Next we would need a Docker Container Template to build and push the Docker Image to Azure Container Registry

In “Build an image” step we connect to Container Registry created in Azure, which will be storing our Docker images. We also select the Dockerfile from our solution. The docker image name includes the Build Id. We change this in the next step.

In “Push an image” step we push the Docker Image to ACR. Note we include the latest tag in the image name which would allow us to store a single image every time the build is run.

Finally we set the trigger for the Build and enable Continuous integration, so every time we make a change to our Git repo a build gets triggered.

We are all set for CI and once we make a code push in GitHub, a build is automatically triggered. Once a build succeeds we will be able to see the repository created in Azure Container registry.

Creating Web App Container for running our Docker Image

We then create a Web App for Container within the same resource group and configure the Web App to use the image from the repository, created as part of the Build process.

Once the Web App is created we just need to configure the Release process with the Web App container.

Setting up your Release Pipeline

We start by creating a new Release pipeline. We will need to define an artifact and a continuous deployment trigger. Note we connect to the Container registry and repository for our Docker Image.

Finally we add a Task for Stage 2. We use an Azure App service deploy Task which points to the App service created earlier and the ACR server name and Image repository name.

We enable the trigger for the Release pipeline and are all set with our Continuous Deployment.

With the pipelines setup in Azure DevOps, every time a code push happens in GitHub the build process would be triggered which would update the Docker Image in ACR, followed by release process which would run the Web App Container with the latest image from Container Registry.

This includes the basic steps on how we can get started on setting up a CI/CD pipeline with Azure DevOps and deploy our applications inside a Docker Container.

In case we want to use AWS services we have to replace Container Registry in Azure with ECR or Elastic Container Registry and use Elastic Container Service or ECS to manage our containers.