Deploying a .NET Core App with Docker and GitHub Actions on Azure – Complete CI/CD Pipeline

In today’s fast-paced software world, automation is king. Manually deploying updates is time-consuming, error-prone, and inefficient. That’s where CI/CD pipelines come in. In this comprehensive guide, we’ll walk you through creating a complete CI/CD pipeline to deploy a .NET Core application using GitHub Actions, Docker, and Azure Web App for Containers.
You’ll learn how to:
- Dockerize a .NET Core web application
- Configure GitHub Actions for CI/CD
- Push a Docker image to Azure Container Registry (ACR)
- Automatically deploy the image to an Azure Web App
Whether you’re a developer, DevOps engineer, or cloud enthusiast, this tutorial will give you a powerful, production-ready deployment setup.
🧰 Prerequisites
Before we start, make sure you have the following:
- A .NET Core application (we’ll use ASP.NET Core 7.0 for this guide)
- GitHub account with a repository for your project
- Azure account with access to create a Resource Group and Web App
- Docker installed on your local machine
- Azure CLI installed (
az
command)
Optional but recommended:
- Visual Studio Code or Visual Studio
- Basic understanding of Docker and GitHub Actions
🗂 Step 1: Create the .NET Core Web Application
If you don’t have an existing .NET Core app, let’s create a new one:
mkdir MyDotNetApp
cd MyDotNetApp
dotnet new webapi -n MyDotNetApp
cd MyDotNetApp
dotnet run
Ensure everything is working by opening http://localhost:5000
.
🐳 Step 2: Dockerize the Application
Create a Dockerfile
in the root directory:
# Stage 1 - Build
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o out
# Stage 2 - Runtime
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "MyDotNetApp.dll"]
Test the Dockerfile locally:
docker build -t mydotnetapp .
docker run -p 8080:80 mydotnetapp
Navigate to http://localhost:8080
to ensure it works.
☁️ Step 3: Create Azure Resources
Let’s prepare Azure for the deployment.
az login
az group create --name MyResourceGroup --location eastus
az acr create --resource-group MyResourceGroup --name MyACRRegistry --sku Basic --admin-enabled true
az acr login --name MyACRRegistry
Create an App Service Plan and Web App:
az appservice plan create --name MyAppPlan --resource-group MyResourceGroup --is-linux --sku B1
az webapp create --resource-group MyResourceGroup --plan MyAppPlan --name MyDotNetWebApp --deployment-container-image-name myacrregistry.azurecr.io/mydotnetapp
🔐 Step 4: Store Azure Credentials in GitHub Secrets
Generate credentials for GitHub to access Azure:
az ad sp create-for-rbac --name "github-cicd" --role contributor --scopes /subscriptions/<subscription-id>/resourceGroups/MyResourceGroup --sdk-auth
Copy the output JSON and go to your GitHub repository:
- Navigate to Settings > Secrets and variables > Actions > New Repository Secret
- Add a secret with name
AZURE_CREDENTIALS
and paste the JSON output
Also add secrets:
AZURE_WEBAPP_NAME
:MyDotNetWebApp
AZURE_REGISTRY_NAME
:MyACRRegistry
⚙️ Step 5: Configure GitHub Actions
Create a folder structure:
mkdir -p .github/workflows
touch .github/workflows/deploy.yml
Here’s a sample deploy.yml
:
name: Deploy to Azure
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up .NET Core SDK
uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.0.x'
- name: Log in to Azure
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Build Docker image
run: |
docker build -t myacrregistry.azurecr.io/mydotnetapp .
- name: Azure Container Registry Login
uses: azure/docker-login@v1
with:
login-server: myacrregistry.azurecr.io
username: ${{ secrets.AZURE_REGISTRY_NAME }}
password: ${{ secrets.AZURE_CREDENTIALS }}
- name: Push image to ACR
run: docker push myacrregistry.azurecr.io/mydotnetapp
- name: Deploy to Azure Web App
uses: azure/webapps-deploy@v2
with:
app-name: ${{ secrets.AZURE_WEBAPP_NAME }}
images: myacrregistry.azurecr.io/mydotnetapp
Push your changes to GitHub:
git add .
git commit -m "Add CI/CD pipeline"
git push origin main
GitHub Actions will automatically build your Docker image, push it to ACR, and deploy it to Azure.
✅ Step 6: Test Your Deployment
Go to the Azure Portal, open your Web App (MyDotNetWebApp), and grab the public URL. Visit it in your browser and confirm your .NET app is live!
Every time you push to the main
branch, the entire pipeline will rerun.
🛠 Tips and Enhancements
- Add stages for testing (e.g.,
dotnet test
) before deploying - Use production and staging environments
- Monitor deployments via Azure App Insights
- Use GitHub environments and approvals for production
- Auto-tag Docker images using
GITHUB_SHA
or date
📦 Bonus: Auto-Tagging Docker Images
Modify your deploy.yml
to include version tags:
- name: Define Docker Tag
run: echo "IMAGE_TAG=$(date +%Y%m%d%H%M%S)" >> $GITHUB_ENV
- name: Build Docker Image
run: docker build -t myacrregistry.azurecr.io/mydotnetapp:${{ env.IMAGE_TAG }} .
- name: Push Docker Image
run: docker push myacrregistry.azurecr.io/mydotnetapp:${{ env.IMAGE_TAG }}
🧠 Conclusion
You now have a fully automated CI/CD pipeline using GitHub Actions, Docker, and Azure! This setup enables continuous deployment with minimal manual effort. You can scale this setup to multiple environments, microservices, and even Kubernetes.
Automation is key to modern software delivery. Start small, iterate fast, and keep improving your pipelines. Happy shipping! 🚀