Posts GitHub Actions: How to build and push a Docker image to Azure Container Registry
Post
Cancel

GitHub Actions: How to build and push a Docker image to Azure Container Registry

Desktop View

In this article, we’ll have a look at how we can use GitHub Actions Workflows to build and push a Docker image in an Azure Container Registry.

Pre-Requisites

  • Basic knowledge of Azure and the Portal
  • Basic knowledge of Git
  • Basic knowledge of GitHub Actions
  • Basic knowledge of Dockerfile
  • Basic knowledge of YAML syntax
  • An Azure subscription (you can get one free here)
  • A GitHub account (you can sign up here)

1. Create the Azure Container Registry (ACR)

First, we’ll want to create the Azure Container Registry that will store our images (as well as the resource group that will hold the container registry). There are multiple ways we can achieve this but for our example, we’ll use the Azure CLI (you can run these commands directly in the Azure Cloud Shell):

1
2
3
4
5
6
7
8
9
10
11
#Optional - This command is only necessary if you're using a local terminal
az login

ACR_RG_NAME="acrTest-RG" #use your own name for this variable
ACR_NAME="eastcanadadevtestacr" #use your own name for this variable

#Creates the resource group that will store the ACR
az group create --name $ACR_RG_NAME --location canadaeast

#Creates the ACR in the resource group that was created earlier
az acr create --resource-group myResourceGroup --name $ACR_NAME --sku Basic

When creating the ACR, please note that the name has to be unique in Azure and contain 5-50 alphanumeric characters. If the ACR_NAME is already taken, please feel free to use another unique name instead for the ACR.

Once the ACR has been created, navigate to it in the Azure portal, go to the “Access Keys”, make sure to enable “Admin user” and take note of the username and password (you’ll need it for a later section):

Desktop View

2. Setup the GitHub Repo

Next, if you don’t have one already, you should create a GitHub repository that will store your code.

Once your GitHub repo has been created, you can push your project’s code to it.

3. Create a Sample Application and Dockerfile

In this section, we’ll create a very simple ASP.Net application and Dockerfile using Visual Studio as an example that will be built and pushed to the ACR. However, if you have your own application and Dockerfile already in GitHub, please feel free to use that instead and skip this section.

The Dockerfile for this example looks like this (to give more context, this Dockerfile resides in the same folder as the .csproj):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["SampleWebApplication.csproj", "SampleWebApplication/"]
RUN dotnet restore "SampleWebApplication/SampleWebApplication.csproj"

WORKDIR "/src/SampleWebApplication"
COPY . .

RUN dotnet build "SampleWebApplication.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "SampleWebApplication.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "SampleWebApplication.dll"]

4. Add ACR Credentials as Secrets in GitHub

Next, we’ll need to store our ACR’s credentials (that you noted earlier) as secrets in GitHub - we wouldn’t want to hardcode any credentials in code, right? ;) To do so, go to the “Settings” tab and select Secrets > Actions as shown below and “New repository secret”:

Desktop View

Once added, they should appear like this and be ready to be used:

Desktop View

Note: Another way we could’ve done this is to put the secrets in an Azure Keyvault and refer to them from our GitHub Workflow

5. Create the GitHub Workflow

Now it’s time to create our workflow in GitHub. To do so, go to your project’s repo in GitHub and go to the “Actions” tab and select “setup a workflow yourself” as shown below:

Desktop View

First, you want to give a nice and meaningful name to your workflow (ok, I admit that the name below might not be that great, but you get the idea):

1
name: SampleWebApp CICD

Next, you’ll want to set the branches that will trigger the workflow (either through a change or pull request). For simplicity, in this example, the workflow is only triggered from the main branch but obviously, you’d want to set this in alignment with your branching strategy:

1
2
3
4
5
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

Finally, let’s write the meat of the workflow. In our example, we have one job (named “build”) that runs on a GitHub-Hosted Ubuntu runner. Note that for this example we’re using a Ubuntu runner but depending on the needs of your build, you might want to use another GitHub-Hosted runner or even your private self-hosted runner. For more info about GitHub-Hosted runners and their capabilities, you can refer to the official documentation About GitHub-Hosted Runners .

1
2
3
4
jobs:

  build:
    runs-on: ubuntu-latest

Our build job would have 3 steps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    steps:
    - uses: actions/checkout@v3

    - name: Azure Container Registry Login 
        uses: Azure/docker-login@v1 
        with:
        # Container registry server url
        login-server: eastcanadadevtestacr.azurecr.io
        # Container registry username
        username: ${{ secrets.ACR_USERNAME }}
        # Container registry password
        password: ${{ secrets.ACR_PASSWORD }} 

    - name: Build and Push the Docker image 
      run:  | 
       docker build ./SampleWebApplication -t eastcanadadevtestacr.azurecr.io/samplewebapp:${{ github.run_id }}
       docker push eastcanadadevtestacr.azurecr.io/samplewebapp:${{ github.run_id }} 

The first step is where we checkout the code from source control (pretty common). Next, we use a step that logs us in to our ACR by referring to the secrets that you created earlier. Finally, we run a docker command that builds and tags the image and another that pushes the image to the ACR.

Below is the full workflow YAML file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
name: SampleWebApp CICD

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:

  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    
    - name: Azure Container Registry Login 
        uses: Azure/docker-login@v1 
        with:
        # Container registry server url
        login-server: eastcanadadevtestacr.azurecr.io
        # Container registry username
        username: ${{ secrets.ACR_USERNAME }}
        # Container registry password
        password: ${{ secrets.ACR_PASSWORD }} 
    
    - name: Build and Push the Docker image
      run:  | 
       docker build ./SampleWebApplication -t eastcanadadevtestacr.azurecr.io/samplewebapp:${{ github.run_id }}
       docker push eastcanadadevtestacr.azurecr.io/samplewebapp:${{ github.run_id }} 

Once you’re done editing your workflow, you can commit it - in our example, we’ll commit directly to master branch for simplicity but you’ll obviously want to respect your branching strategy for this part:

Desktop View

6. Commit and push your code

Once your workflow has been setup, you can start making changes to your repository’s code and the workflow will automatically get triggered. You can monitor your workflow under the “Actions” tab:

Desktop View

Finally, when the deployment is done, you can go into the ACR to have a look at your newly pushed image:

Desktop View

Congratulations, you have pushed your image to an Azure Container Registry using GitHub Actions Workflow!

Next Steps

Now that we have the image in our ACR, the next steps that we could do would be to pull that image using GitHub Actions Worflows and deploy it to Azure.

I hope this article has been useful to you! Again, and as always, I’d love to hear your feedback and if you have any questions or something you’d like to add based on your experience, please let me know in the comments section below!

If you’d like to see more content like this in the future and keep in touch, feel free to follow me on Twitter and LinkedIn!

This post is licensed under CC BY 4.0 by the author.

5 Ways to Deal with Imposter Syndrome in Tech

GitHub Actions: How to pull a Docker Image from Azure Container Registry and deploy to Azure App Service in multiple environments

Comments powered by Disqus.