Deploying a Docker Container on Azure

Escaping the dreadful pit of localhost

Published 28 April, 2023

Motivation

I've been playing around with azure a fair bit recenty and I wanted to deploy a docker container for some long-running tasks. I've done this before but I wanted to document the process for future reference.

Updated 1 May with additional information on how to integrate with Github

Create the Registry

create-container

az group create --name <nameOfResourceGroup> --location <location>
 

Try to pick a location that is close to you. This way, you'll have lower latency. I chose southeastasia because I'm in Singapore.

Next, you'll need to then create a registry. This will store all your docker images that you wish to work .

create-registry

az acr create --resource-group schulz --name <nameOfRegistry> --sku Basic
 
 

You'll get a massive JSON file that'll be output to your server. Make sure to look through it and save two values

response.json

{
    //...
    loginServer: <Where your registry resides>,
 
    //...
 
}
 

Next, you'll want to login to your az registry. You can do so by running the following command

az acr login --name <nameOfRegistry>

If it's successfull, you should get the following response that looks something like this

(venv) ➜  filesplitter git:(main) ✗ az acr login --name <nameOfRegistry>
Login Succeeded

Lastly, enable your admin user on the registry

 az acr update -n <nameOfRegistry> --admin-enabled true

Tag Your Image

You can see a list of images that you have locally with docker using

docker images

This will in turn give you a list of images that you have locally.

REPOSITORY                                    TAG                IMAGE ID       CREATED          SIZE
<nameOfImage>                                 latest             628f83ffe348   26 minutes ago   1.35GB

You'll want to tag the image that you want to push to your registry. You can do so by running the following command

docker tag <nameOfImage> <loginServer>/<nameOfImage>:v1

Your image will then be identified with the tag of <loginServer>/<nameOfImage>:v1.

Note that the name of the local image does not need to match the name of the image on the registry.

You can then verify that your image has been pushed to the registry you created by running the command

az acr repository list --name <nameOfRegistry> --output table

which should in turn give you the output as

Result
-------------
<nameOfImage>

Deploying your image

Let's do a quick recap of what we've done

  1. We've succesfully created a new registry to house our docker image
  2. We've tagged our image and pushed it to the registry

amd now all that's left is to tell azure that we want to deploy our image. We can do so with the following command

deploy-container

az container create --resourceGroup <nameOfResourceGroup> --name <nameOfContainer> --image <imageTag> --dns-name-label <nameOfContainer> --ports <port you want to expose> --registry-username <nameOfRegistry> --registry-password <passwordOfRegistry> --environment-variables <any environment variables you might want to expose>

If you have an .env file which looks like this

env1=value1
env2=value2

Now just run the command and you're good to go!.

you should pass in the environment variables as 'env1'='value1' 'env2=value2'. Note that you'll need to wrap the environment variables in single quotes.

Bonus Steps - Github Actions

While optional, I highly recommend automating the release steps of your new docker container. This way you'll be able to just push and get everything set up without scrambling for your terminal.

On a high level, what we need to do is

  1. Create a new user with credentials to push to your azure container registry
  2. Create a new github action that will build and push your docker image to your registry
  3. Profit

Step 1 : Creating Credentials

We can connect your github repository to your azure container registry. This way, whenever you push to your repository, it'll automatically build and deploy your container to your registry.

First, we'll need to create a new set of credentials for our github runner. We can do so by running the command

 az group show \
  --name <nameOfResourceGroup> \               
  --query id --output tsv

This should return a group Id as

/subscriptions/a-b-c-d-e/resourceGroups/nameOfResourceGroup
az ad sp create-for-rbac \
  --scope /subscriptions/a-b-c-d-e/resourceGroups/nameOfResourceGroup \
  --role Contributor \
  --sdk-auth

This should give you a output similar to

{
  "clientId": "xxxx6ddc-xxxx-xxxx-xxx-ef78a99dxxxx",
  "clientSecret": "xxxx79dc-xxxx-xxxx-xxxx-aaaaaec5xxxx",
  "subscriptionId": "xxxx251c-xxxx-xxxx-xxxx-bf99a306xxxx",
  "tenantId": "xxxx88bf-xxxx-xxxx-xxxx-2d7cd011xxxx",
  "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
  "resourceManagerEndpointUrl": "https://management.azure.com/",
  "activeDirectoryGraphResourceId": "https://graph.windows.net/",
  "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
  "galleryEndpointUrl": "https://gallery.azure.com/",
  "managementEndpointUrl": "https://management.core.windows.net/"
}

You'll want to save this JSON output and keep it for a later step. Take note especially of clientId

Next, you'll need to give the service principal acccess to your azure container registry. You can do so by running the following command

registryId=$(az acr show \
  --name <registry-name> \
  --resource-group <resource-group-name> \
  --query id --output tsv)
az role assignment create \
  --assignee <ClientId> \
  --scope $registryId \
  --role AcrPush

Step 2 : Creating Github Action

Here is the github action that I am currently using to deploy my containers

deploy.yml

name: Azure Docker Container Deployment
 
on:
  push:
    branches:
      - main
 
jobs:
  deploy:
    runs-on: ubuntu-latest
 
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
 
      - name: "Login via Azure CLI"
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
 
      - name: "Build and push image"
        uses: azure/docker-login@v1
        with:
          login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
          username: ${{ secrets.REGISTRY_USERNAME }}
          password: ${{ secrets.REGISTRY_PASSWORD }}
 
      - run: |
          docker build . -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/${{secrets.IMAGE_NAME}}:${{ github.sha }}
          docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/${{secrets.IMAGE_NAME}}:${{ github.sha }}
 
      - name: "Deploy to Azure Container Instances"
        uses: "azure/aci-deploy@v1"
        with:
          resource-group: ${{ secrets.RESOURCE_GROUP }}
          dns-name-label: ${{ secrets.RESOURCE_GROUP }}${{ github.run_number }}
          image:
            ${{ secrets.REGISTRY_LOGIN_SERVER }}/${{secrets.IMAGE_NAME}}:${{
            github.sha }}
          registry-login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
          registry-username: ${{ secrets.REGISTRY_USERNAME }}
          registry-password: ${{ secrets.REGISTRY_PASSWORD }}
          name: ${{secrets.DEPLOYMENT_NAME}}
          location: "southeastasia"
          secure-environment-variables: |
            key1 = ${{secrests.key1}}
            key2 = ${{secrests.key2}}

You'll need to log into azure to get some of these credentials. Simply go to Home > Container Registries > Name Of Registry > Access Keys. You should see a screen like what I've linked below.

Azure Keys Config Screen

Here are some of the important variables to take note of which you should set in your github pipeline secrets.

  • AZURE_CREDENTIALS : This is the JSON output from the previous step
  • REGISTRY_LOGIN_SERVER : This is the login server of your registry. You can find this by running the command az acr show --name <nameOfRegistry> --query loginServer --output tsv
  • REGISTRY_USERNAME : This corresponds to the UserName field in the image above
  • REGISTRY_PASSWORD : Just choose either one of the passwords in the image above in password and password2 fields
  • IMAGE_NAME : This is the name of your image. For example, if your image is myImage:latest, then you'll want to put myImage here. This way you get a consistent value
  • RESOURCE_GROUP : This is the name of your resource group

With this, you should be able to simply deploy and push your container to your registry by pushing to your repository by creating a file with the path of .github/workflows/deploy.yml.

Enjoy!