DEV Community

Renicius Pagotto
Renicius Pagotto

Posted on • Updated on

Publishing Docker images to Azure Container Registry with GitHub Actions

Hi everyone,

In today’s post, we will discuss how to upload Docker images to Azure Container Registry. To fully understand the step-by-step process, let’s first explore some key concepts related to the topic.

Azure Container Registry

In a nutshell, Azure Container Registry (ACR) is a service specialized in storing artifacts, including Docker images. For more information, you can access this post where I explain step by step how to create and use it.

GitHub Actions

GitHub Actions is a continuous integration (CI) and continuous delivery (CD) service provided by GitHub that lets you automate, customize, and execute software development workflows directly in your GitHub repository.

For our demonstration, we will use a .NET 8 Web API application which is essentially the default template with a Dockerfile.

GitHub Action Pipeline

This is the complete declaration of the pipeline file (.yml) where the az-registry step is the main focus. As an additional bonus of knowledge, there is a step to upload the same image to GitHub Container Registry and there is also a step to deploy the image to Azure Web Apps.

name: Build and Deploy

on:
  workflow_dispatch:
  push:
    tags:
      - '*.*.*'

env:
  IMAGE_NAME: "product-service"
  GH_REGISTRY: "ghcr.io"
  AZ_REGISTRY: "azdevdaysrpf.azurecr.io"
  AZURE_WEBAPP_NAME: az-devdays-appservice

jobs:
  gh-package:
    name: Publish | GitHub Registry
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to the GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.GH_REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GH_REGISTRY_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.GH_REGISTRY }}/${{ github.actor }}/${{ env.IMAGE_NAME }}

      - name: Build and Push Image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}

  az-registry:
    name: Publish | Azure Container Registry
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.meta.outputs.version }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to the Azure Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.AZ_REGISTRY }}
          username: ${{ secrets.AZ_SP_CLIENT_ID }}
          password: ${{ secrets.AZ_SP_CLIENT_SECRET }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.AZ_REGISTRY }}/${{ env.IMAGE_NAME }}

      - name: Build and Push Image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}

  deploy:
    name: Azure Web App Deployment
    runs-on: ubuntu-latest
    needs: [ gh-package, az-registry ]
    steps:
      - name: Login Azure
        env:
          AAD_SERVICE_PRINCIPAL_CLIENT_ID: ${{ secrets.AZ_SP_CLIENT_ID }}
          AAD_SERVICE_PRINCIPAL_CLIENT_SECRET: ${{ secrets.AZ_SP_CLIENT_SECRET }}
        run: |
          az login --service-principal -u ${{ secrets.AZ_SP_CLIENT_ID }} -p ${{ secrets.AZ_SP_CLIENT_SECRET }} --tenant ${{ secrets.AZ_TENANT_ID }}
          az account set -s ${{ secrets.AZ_SUBSCRIPTION_ID }}
          az account show

      - name: Azure Web Apps Deployment
        uses: azure/webapps-deploy@v3
        with:
          app-name: ${{ env.AZURE_WEBAPP_NAME }}
          images: ${{ env.AZ_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.az-registry.outputs.version }}
Enter fullscreen mode Exit fullscreen mode

Let's start with the first part of the pipeline where below we have an image and also the explanation.

Image description

name: The name of the pipeline.

on: Specifies the trigger for the pipeline. In this case, the pipeline is triggered every time a new tag (git tag) is pushed. We also define the format of the git tag required to execute the pipeline, typically following the standard versions like 0.0.1 or 1.0.0.

env: Represents the global environment variables for the pipeline context.

IMAGE_NAME: The name assigned to the Docker image.

AZ_REGISTRY: The URL of the Azure Container Registry.

Let's dive into the az-registry stage now and explain the steps in detail, as this is where all the crucial actions take place.

Image description

In this stage, we are using a Linux runner called ubuntu-latest.

Checkout Repository: This step downloads the repository to the GitHub runner.

Docker Buildx: This installs Docker along with the extended plugin called Buildx.

Login to Azure: We log in to Azure to enable image uploads using a Service Principal with contributor access to the Azure Container Registry.

Image description

Extract Metadata: Retrieve metadata (such as tags and labels) and define the full name of the image.

Build and Publish: In this final step, we run the Dockerfile, tag the image named in the previous step, and upload it to Azure Container Registry.

Finally, to execute the pipeline, define a tag using the git tag command and push the tag to the origin. Here are examples of the commands.

git tag 1.0.0
git origin push 1.0.0

Image description

Did you enjoy this post? Want to chat more about it? Leave a comment with your questions and ideas, or connect with me on LinkedIn.

GitHub Repository: https://github.com/reniciuspagotto/az-devdays-dotnet-container?wt.mc_id=studentamb_72239

Top comments (0)