Containers provide new levels of virtualization, isolating application and developer dependencies from infrastructure and operational requirements. What remains, however, is the need to address how this application virtualization is managed and patched over the container lifecycle.

Most companies and developers rely on Docker Desktop for that purpose, as it is lightweight, works pretty well for both Windows, Linux and Mac, takes care of important configuration details on guest OS, and so on, but mainly because it is free (well, that’s no longer entirely true).

You might have heard the news, but if don’t, here you go. Starting August 31st Docker Desktop, developers working for a company which has over 250 employees or have +$10 million in revenue will have until January 31st 2022 to sign up for a paid subscription to keep using the Docker’s solution. While it will remain free to use for small companies, personal use or education purposes, enterprise organizations will be facing an additional spend in their accounts, which might led them to explore opportunities off Docker Desktop box.

Actually, this is happening already and this post is a suggestion that you might considering within your organization moving forward.

Azure Container Registry (ACR) Tasks

Container Registry is a built-in, secure, high-scalable and first-class citizen platform service for hosting and managing container images in Microsoft Azure. It is based on open-source Docker Registry 2.0 and support all formats described by Open Container Initiative (OCI). It is ideal to privately manage container images no matter how large a company is.

ACR has been around for while now and has been receiving exciting new features over the last couple years. One of them is what Microsoft calls ACR Tasks, which allows automation on top of the container images sitting into its domain.

While you can put tasks (single or multi) to work based on triggers (code update, image update or on a schedule), one very useful feature that could be easily leveraged to build out docker images out-of-the-box (breaking dependency to Docker Desktop) is what ACR defines as “quick task”.

Quick tasks allows you to build and push a single container image to a container registry on-demand, in Azure, without needing a local Docker Engine installation. Think docker builddocker push in the cloud, but executing those via Azure CLI. Figure 1 depicts what that process might look like.

Figure 1. Using ACR Tasks in replacement to docker build and suggestively pushing to ACI

This is exactly the process I’m going to get into from this moment on in this article. Bear with me!

Building, pushing and publishing an App via ACR Tasks

The application we’re going to use for this sample is available in this repository in Github. If you want to follow along, I recommend forking it to your own Github account (so that you have full administrative access to it) and from there, cloning it into your working machine.

To interact with ACR Tasks we’re going to rely on Azure CLI. Therefore, if you don’t have Azure CLI installed in your system, I recommend you to do so now. If you haven’t touched Azure CLI yet, it is pretty lightweight and easy to install. All the instructions for the various operational systems are available here.

All the scripts presented in this article target Bash environments. If you are running Azure CLI in CMD or PowerShell, it might be slightly different.

Needless to say but, but I want to make sure you know it: you’re going to need to have an active Azure subscription you got access to handy, as we’re going to interact directly with a cloud service. At the corporative level, if you don’t have access to the resources you need in Azure to accomplish what is proposed here, you can always ask your cloud admin to set that up for you.

Step 1. Create a new resource group and ACR

This step-by-step guide assumes you don’t have any of the Azure resources needed in place. That’s why, after logging into our Azure subscription, we’re going to start creating a new resource group. Gist 1 below outlines how to do so.

Gist 1. Logging user in Azure and creating a new Resource Group

Now that we have a place to logically group our resources together, let’s create a new instance of Azure Container Instances. Gist 2 below brings us what is needed for us to get it done.

A thing to notice about the code presented by Gist 2 is the property --admin-enabled true. We need this to allow to log a service principal we’re going to create later on with ACR to deploy our image into Azure Container Instances.

Gist 2. Creating a new ACR

Step 2: Build and push docker image

Next, assuming you have the application code already cloned into your working machine, let’s navigate to app’s root directory (where our docker file is actually sitting on). Figure 2 shows how it looks like in my machine.

Figure 2. Accessing app’s root directory

Once in there, we can build out our docker image in ACR. The Gist 3 below describes the exact command you need to run to do so.

Please notice that you should replace --image‘s property value with the name you’re attributing to your container image. Also, following docker’s best practices, you should give it a version (for example, v1 or whatever makes sense to you).

Gist 3. Builds a new docker image from ACR

What is happening behind the scenes is: ACR is wrapping up what docker calls “context” of the build and sends it up to ACR. ACR then triggers a task that not only runs the docker build command for you (it does know how to solve it internally), but also pushes it into a new repository in ACR. Pretty neat, huh?!

In order to validate if image was properly built and pushed, you can run the command “az acr repository list -n $ACR_NAME -o table“. This will bring up in format of a table, all the repositories sitting on your ACR, including the new one just created.

Figure 3 depicts the results I get when performing that command line.

Figure 3. Sample app image successfully built and pushed to ACR

Step 3: Deploying sample app into Azure Container Instances (Optional)

Thanks to ACR, now we have our docker image successfully built and pushed to our enterprise docker repository in Azure. Now, we’re free to deliver our app in whatever container service (in or out Azure) to run.

I want to continue in Azure and because our sample app is very lightweight, I’m going to stick with Azure Container Instances service, which allows us to running single container instances in a very scalable, reliable and cost-effective way.

If you want to know more about Azure Container Instances, please, take a read here. If you are interested on learning more about all the options for hosting containers in Azure, you should spend some time reading the content available here.

To deploy our application into ACI, we’re going to need to securely access our ACR instance (remember, we protected our ACR instance against anonymous access by enabling admin account when we created it) to pull our app’s image and then, deploy it into ACI.

We could use plain username and password to make that access to happen. But that’s is easily “breachable”. That’s the reason by which we will rely in another service in Azure to securely store ACR’s username and password; Azure KeyVault.

Then, we’re going to attribute to a service principal we’re going to create the specific permission to only pull username and password from the vault for later deployment. Zero trust always comes first.

Gist 4 outlines the process of creating a new Azure KeyVault, two new secrets (one for username and another one for password) in that new vault, while creates a new service principal and attributes the proper permission (pull) to it.

Gist 4. Creating a new vault, service principal and secrets

To validate everything went well at the end, you can run the command line “az keyvault secret list --vault-name $AKV_NAME -o table“. It should give you back something pretty similar t what the Figure 4 depicts.

Figure 4. Listing secrets created in Azure KeyVault

Now we have our credentials in place, we’re ready to deploy the sample app into ACI. To make that happen, just execute the command outlined by Gist 5. After a couple seconds (literally), you should be able to see that the command successfully ran and your App is now ready to reached from ACI.

You must have noticed that there are couple of variables for you to replace in that code, but I wanted to make sure you did by explicitly calling it out.

Gist 5. Deploying sample app’s image from ACR

Running the command “az container attach --resource-group $RG --name your-aci-name” will give you access to the realtime logging events happening with that deployment. Couple seconds after, you should be able to see that your container tuned to “Ready” state and you can hit it from your browser.

Figure 5 shows my application successfully running.

Figure 5. Successfully running sample app from ACR

That’s it. Hope it helps. See you next time!


2 Comments

James Vacca · February 2, 2022 at 4:39 pm

Great job explaining the situation and how to use ACR to overcome the challenge!

Leave a Reply

Avatar placeholder

Your email address will not be published.