Skip to main content

Dockerize your .NET Core Webapp and deploy with CI/CD

In this blog post we're going to;

1. Build a .NET Core web app
2. Confirm the web app works
3. Build a Docker image from that web app
4. Build an Azure Container Registry to store our image
4. Deploy our Docker image via CI/CD to Azure WebApps with Azure DevOps

Before building your Docker image, ensure you are using Linux containers if you are working on Windows 10. Open up the Docker application and select "Switch to Linux containers...."

Pre-requisites;
1. Visual Studio (Community Edition is fine)
2. Visual Studio Code
3. An Azure subscription
4. An Azure DevOps Project
5. Docker installed on your desktop

Code for this project can be found at: https://github.com/AdminTurnedDevOps/TheLifeOfAnEngineerBlog/tree/master/DockerizeDotNetCoreApp

First let's open up a terminal (I'm using Windows Terminal, but you can use PowerShell) and run dotnet new to see our options. In the options, we're going to want webapp



Create a new directory for your webapp to go in. For example, create a directory called "web" on your desktop, go into that directory (cd web), create a new directory called web inside of the existing web directory, and run dotnet new webapp to create your webapp.


Now within the web/web directory, run dotnet publish to pack the application and it's dependencies into our directory and then run dotnet run to run our webapp locally. As you can see from the screenshot below, I've customized the HTML a bit in mine.




Now that we know our .NET Core webapp works, we're ready to package it into a Docker image. For this, we'll need a Dockerfile.

Below you will see the Dockerfile being used (also available at the GitHub link in the beginning of this blog post). This Dockerfile uses the .NET Core SDK and the .NET Core runtime.

FROM mcr.microsoft.com/dotnet/core/sdk AS build-env
WORKDIR /appdir
EXPOSE 80
EXPOSE 443

# Copy csproj and restore as distinct layers
COPY web/*.csproj ./
RUN dotnet restore

# Copy .NET Core Web App. Release packs the application and its dependencies into a folder for deployment to a hosting system
COPY ./web ./
RUN dotnet publish -c Release -o out

# Build the runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet
WORKDIR /appdir
COPY --from=build-env /appdir/out .
ENTRYPOINT ["dotnet", "web.dll"]


Please ensure that your Dockerfile is at the root directory where your web directory is because as you can see in the Dockerfile, it is specifying the web directory in quite a few places. Your directory structure should now look like the screenshot below.



We're now ready to build our Docker image. Please run docker build -t any_app_name_you_want . from the directory that contains the Dockerfile. I've named mine webapp2.



Now we have our Docker image that contains our webapp. We're now ready to create an ACR (Azure Container Registry) to store our Docker image. I'm naming mine "mjlreg" and putting it in my "Dev2" resource group.

az acr create -g Dev2 -n mjlreg --sku basic

Now that my registry is created, we need to log into it at our terminal.

az acr login --name mjlreg

After we create our registry and log into it, we need to tag our docker image with our registry name and push the Docker image to ACR (Azure Container Registry). Please note that my image name is "webapp2" because that's what I named my image locally.

docker tag webapp2 mjlreg.azurecr.io/ms/webapp2
docker push webapp mjlreg.azurecr.io/ms/webapp

Check your Azure Container Registry and you should now see your image. Please copy your registry path (everything after docker pull) as we'll need it in the coming section



Alright, let's take a minute to reflect on what we've done so far.

1. We have create a .NET Core web app and ensured it worked properly by running it locally.
2. We created a Docker image based on that web app so we can containerize our application.
3. We build a Docker registry so we can store our image in Azure.

We're now ready to move over to Azure DevOps.

Open up Azure DevOps and choose one of your projects. Head over to pipelines. Choose where your code is (mine is in Azure Repos). For configuring your pipeline, choose "Starter pipeline".




Your YAML pipeline should be the below (Also in my GitHub that I linked at the beginning of this blog post). The inlineScript is called "createWebApp.ps1" in the GitHub repo.


trigger:
master

pool:
  vmImage'ubuntu-latest'

steps:
taskAzureCLI@2
  inputs:
    azureSubscription'your_sub_name'
    scriptType'pscore'
    scriptLocation'inlineScript'
    inlineScript: |
      param(
          [string]$RG = your_resource_group,
          [string]$appPlanName = your_app_plan_name,
          [string]$appName = your_web_app_name
      )
      
      az appservice plan create -g $RG -n $appPlanName --sku B1 --is-linux
      az webapp create -g $RG -p $appPlanName -n $appName -i docker_image_registry_path_in_acr

We're now ready to run our YAML pipeline.



If we head over to App Services in Azure, we can see our web app running. Click on the URL and you'll see your app has been deployed.


Thanks for reading!

Comments

Popular posts from this blog

Run PowerShell code with Ansible on a Windows Host

Ansible is one of the Configuration Manager kings in the game. With it's easy-to-understand syntax and even easier to use modules, Ansible is certainly a go-to when you're picking what Configuration Management you want to use for your organization. Your question may be "but Ansible is typically on Linux and what happens when I'm in a Windows environment?". Luckily I'm here to tell you that Ansible will still work! I was pleasantly surprised with how easy it is to use Ansible on Windows with a little WinRM magic. Let's get started.

Pre-requisites for this post:
1) WinRM set up to connect to your Windows host from Ansible
2) Ansible set up for Windows Remote Management
3) SSH access to the Ansible host
4) Proper firewall rules to allow WinRM (port 5985) access from your Ansible host to your Windows host
5) Hosts file set up in Ansible that has your IP or hostname of your Windows Server.
6) At least one Linux host running Ansible and one Windows Server host …

Running PowerShell commands in a Dockerfile

As Docker continues to grow we are starting to see the containerization engine more and more on Windows. With the need for containers on Windows, we also need the same automation we get in Linux with Dockerfiles. Today we're going to create a Dockerfile that runs PowerShell cmdlets.
Prerequisites; 1. Docker for Windows
2. A code editor (VSCode preferred)

Let's go ahead and get our Dockerfile set up. Below is the Dockerfile I used for this post.

from mcr.microsoft.com/windows/servercore:1903 MAINTAINER Michael Levan RUN powershell -Command Install-WindowsFeature -Name Web-Server RUN powershell -Command New-Item -Type File -Path C:\ -Name config
As you can see from the above, this is a tiny Dockerfile. What this will do is install the IIS Windows 

Feature and create a new file in C:\ called "config".
You should see something very similar to the below screenshot;

Next let's create a running container out of our image. First we'll need to run docker container ls to

 get o…

DevOps tooling in the Microsoft realm

When I really started to dive into automation and practicing DevOps with specific tooling, there were a few key players. At the time Microsoft was not one of them. They were just starting to embrace the open source world, including the art and practice of DevOps. Since then Microsoft has went all in and the tech giant has made some incredible tooling. Recently I switched to a Microsoft-heavy environment and I love it. I went from AWS/Python/Ansible/Jenkins to Azure/PowerShell/ARM/Azure DevOps. My first programming language was PowerShell so being back in the saddle allowed me to do a full circle between all of the different types of tooling in both worlds. Today I want to share some of that tooling with you.

The first thing I want to talk about is ARM. What is ARM? ARM is a configuration management tool that allows you to perform software-defined-infrastructure. Much like Ansible and Terraform, ARM allows you to define what you want your environment to look like at scale. With ARM, yo…