Sharing containers from private registry in Azure
docker containers azure

This post is about using Azure Container Registry along with Azure Container Instances and Azure Active Directory to host and share Docker images (Duckling in this example).
July 16, 2019

Several times I found myself in a situation where I built a Docker container and wanted someone else to be able to use it, without the image being completely public. Docker Hub gives one private repo for free, but that's not much, so I learned how to share containers through Microsoft Azure.


This post is about using Azure Container Registry along with Azure Container Instances and Azure Active Directory to host and share Docker images (Duckling in this example).


I'm using Docker for Windows.

I also have an Azure Subscription.

My editor of choice is Visual Studio Code.

Deployment and management could be done through Azure CLI, but I still prefer the Portal in Microsoft Edge.

Finally, as a true fanboy, I work in the new Windows Terminal Preview.

The container

Let's say that the goal for today is to build and share an image of Duckling - engine for working with language rules (such as date resolution in various languages).

Thankfully Duckling provides us with a Dockerfile. Let's store this file locally and build local image. (It's not necessary to clone the whole repo, since it actually runs it's own git clone on build.)

> cd Duckling
> ls
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        7/16/2019   1:01 PM            584 Dockerfile

> docker build -t duckling .

Make sure you have assigned enough memory to the Docker host - I had to encrease mine to 4 GB, otherwise Duckling wouldn't build.

4 GB of RAM assigned to Docker

Then you should be able to run the container locally:

> docker run -it duckling
no port specified, defaulting to port 8000                                             Listening on

Container registry

Instead of Docker Hub we will be pushing our new image to a private repository hosted in Azure.

Sign in to the Azure Portal.

Click + Create a resource.

Search for Container Registry.

Container Registry resource from Microsoft

Click Create and fill the form.


Click Create again and wait for the resource to be provisioned.

It should take just a few seconds and your registry will be ready.

Push to registry

To push to this registry, you need login information. Go to the Access keys section and keep it open.


We enabled the admin user option to make pushing and management easier. It's not recommended to share these credentials with others. We will assign pull rights to this repository later.

Back in your Docker host, tag your image properly (, login to your registry and push.

> docker tag duckling
> docker login
Username: mujduck
Login Succeeded

> docker push The push refers to repository [] db85d213478d: Pushing [> ] 14.04MB/2.768GB df9ed2310df0: Pushing [> ] 27.69MB/1.387GB fdf9e916fe56: Pushed 1481a6d3eca1: Pushed 70f2b8a9f544: Pushed 08d2fdc202cd: Pushing [==============================> ] 13.2MB/15.32MB 4dc4aaa29ba4: Pushing [=> ] 24.44MB/1.156GB e2a8a00a83b2: Pushing [=> ] 3.25MB/100.6MB

Assign access to the registry

In order to share this image with others, create an identity in Azure Active Directory and assign it to the container registry with the AcrPull role.

In Azure Portal go to Azure Active Directory.

Select App registrations and + New registration.

New registration button

Choose a name, don't change anything else and click Register.

Make note of the Application (client) ID value:

Application ID in AAD

In the Certificates & secrets section click + New client secret.

Name it and click Add.

New secret

Copy the value, it will not be shown again!

Copy the secret value

Go back to your Container Registry instance.

Select Access control (IAM).

Container registry Access control

Click Add in the Add a role assignment box.

Add a role assignment

Change Role to AcrPull.

Find your app by ID or name in the Select box.

Add role assignment blade

Select it and click Save.

Pulling the container

What you now share with the other person? Docker image name, repository name, application ID and password/secret.

> docker login
Username: 33107716-65b9-4e61-b266-73834c33953c
Login Succeeded

> docker pull

> docker run -it no port specified, defaulting to port 8000 Listening on

Running the container in Azure

Finally, let's release our container from localhost and make it available to the world! Microsoft Azure has a service dedicated to Docker container hosting in a fully managed environment - Container Instances.

Go to Azure Portal.

Click + Create a resource.

Search for Container Instances.

Select Image type to be Private.

Image name = (the full image name)

Image registry login server = (no HTTP or any other protocol)

Image registry user name = 33107716-65b9-4e61-b266-73834c33953c (App ID)

Image registry password = ... (whatever secret was generated for you)

OS type = Linux

Size can stay default (1 CPU, 1.5 GB memory, 0 GPUs).

Create container instance

Move next to the Networking tab.

There are two ways to make Duckling available from the internet: either expose the default port 8000, or instruct Duckling to listen on any other port by setting the PORT environmental variable and port on this tab. I prefer port 80, so that's what I'll do.

Move next to the Advanced tab.

Add the PORT environmental variable with value 80.

Move to Review + Create and then click Create.

Provisioning of this particular container will take some time, because it's quite big (more than 5 GB).

Once it's done you can check that the container is running by opening its IP address (can be found in the Overview section) in a browser:



Useful commands for Azure CLI as an alternative to clicking through Portal:

az group create -n Duckling -l uksouth

az acr create -g Duckling -n mujduck --sku Basic

az acr login --name mujduck

az container create -g Duckling -n myducklingcont --ports 80 --ip-address public --location uksouth --registry-login-server --image --registry-username <username> --registry-password <password> --environment-variables PORT=80 --os-type Linux

Found something inaccurate or plain wrong? Was this content helpful to you? Let me know!