Onboarding : Modern Applications


  • Key concepts
  • Using Azure container for containerized web application
    • Azure Container Registry
      • Azure Container Registry Tasks
    • Azure Container Instance (ACI)
      • Create an Azure Container Instance (ACI)
      • ACI restart-policies
      • ACI check log, state, events
      • ACI set environment variables
      • ACI data volumes
  • Using Azure APP Service

Related topics

Key concepts

  • Docker : Docker is a technology that enables you to deploy applications and services quickly and easily.
  • Docker app : A Docker app runs using a Docker image
  • Docker image : A Docker image is a prepackaged environment containing the application code and the environment in which the code executes [more].
  • Container
  • Docker registries/Docker Hub: is a repository of docker images https://hub.docker.com/
  • Azure container registry
  • Containerized web application : A web app so that it can be deployed as a Docker image and run from an Azure Container Instance
  • Azure Container instance

Using Azure container for containerized web application

  • Rapid deployment is key to business agility
  • Containerization saves time and reduces costs.
  • Multiple apps can run in their isolated containers on the same hardware.

Scenario: Suppose you work for an online clothing retailer that is planning the development of a handful of internal apps but hasn’t yet decided how to host them. You’re looking for maximum compatibility, and the apps may be hosted on-prem, in Azure or another cloud provider. Some of the apps might share IaaS infrastructure. In these cases, the company requires the apps isolated from each other. Apps can share the hardware resources, but an app shouldn’t be able to interfere with the files, memory space, or other resources used by other apps. The company values the efficiency of its resources and wants something with a compelling app development story. Docker seems an ideal solution to these requirements. With Docker, you can quickly build and deploy an app and run it in its tailored environment, either locally or in the cloud.

To build a customized docker image for your pplication refer to Docker, container, Kubernetes post. In this post we focus on work with Azure Container Registry.

  • Azure Container Instance loads and runs Docker images on demand.
  • The Azure Container Instance service can retrieve the image from a registry such as Docker Hub or Azure Container Registry.
Azure Container Registry
  • it has a unique url
  • these registries are private
  • need authentication to push/pull image
  • pull and push only with docker CLI or azure CLI
  • has replication feature in premium SKU (geo-replicated image)
Standard SKU doesn’t support Replications
  • After change SKU to premium then geo-replication can be used
# Deploy a Docker image to an Azure Container Instance

az login

az account list

az account set --subscription="subscription-id"

az account list-locations --output table

az group create --name mygroup --location westeurope

# Different SKUs provide varying levels of scalability and storage.
az acr create --name parisaregistry --resource-group mygroup --sku [standard|Premium] --admin-enabled true
# output -> "loginServer": "parisaregistry.azurecr.io"

# for a username and password.
az acr credential show --name parisaregistry

# specify the URL of the login server for the registry.
docker login parisaregistry.azurecr.io --password ":)" --username ":O" # or using--password-stdin

# you must create an alias for the image that specifies the repository and tag to be created in the Docker registry
# The repository name must be of the form *<login_server>/<image_name>:<tag/>.
docker tag myapp:v1 myregistry.azurecr.io/myapp:v1 # myregistry.azurecr.io/myapp:v1 is the alias for myapp:v1

# Upload the image to the registry in Azure Container Registry.
docker push myregistry.azurecr.io/myapp:v1

# Verify that the image has been uploaded
az acr repository list --name myregistry

az acr repository show --repository myapp --name myregistry
Azure Container Registry Tasks [Source]
# Dockerfile with azure container registry tasks

FROM    node:9-alpine
ADD     https://raw.githubusercontent.com/Azure-Samples/acr-build-helloworld-node/master/package.json /
ADD     https://raw.githubusercontent.com/Azure-Samples/acr-build-helloworld-node/master/server.js /
RUN     npm install
CMD     ["node", "server.js"]

After creating the docker file run the following codes

az acr build --registry $ACR_NAME --image helloacrtasks:v1 .

# Verify the image
az acr repository list --name $ACR_NAME --output table

# Enable the registry admin account
az acr update -n $ACR_NAME --admin-enabled true

az acr credential show --name $ACR_NAME

# Deploy a container with Azure CLI
az container create \
    --resource-group learn-deploy-acr-rg \
    --name acr-tasks \
    --image $ACR_NAME.azurecr.io/helloacrtasks:v1 \
    --registry-login-server $ACR_NAME.azurecr.io \
    --ip-address Public \
    --location <location> \
    --registry-username [username] \
    --registry-password [password]

az container show --resource-group  learn-deploy-acr-rg --name acr-tasks --query ipAddress.ip --output table

# place a container registry in each region where images are run
# This strategy will allow for network-close operations, enabling fast, reliable image layer transfers.
# Geo-replication enables an Azure container registry to function as a single registry, serving several regions with multi-master regional registries.
# A geo-replicated registry provides the following benefits:
#       Single registry/image/tag names can be used across multiple regions
#       Network-close registry access from regional deployments
#       No additional egress fees, as images are pulled from a local, replicated registry in the same region as your container host
#       Single management of a registry across multiple regions

az acr replication create --registry $ACR_NAME --location japaneast

az acr replication list --registry $ACR_NAME --output table

Azure Container Registry doesn’t support unauthenticated access and require authentication for all operations. Registries support two types of identities:

  • Azure Active Directory identities, including both user and service principals. Access to a registry with an Azure Active Directory identity is role-based, and identities can be assigned one of three roles: reader (pull access only), contributor (push and pull access), or owner (pull, push, and assign roles to other users).
  • The admin account included with each registry. The admin account is disabled by default.

The admin account provides a quick option to try a new registry. You enable the account and use its username and password in workflows and apps that need access. Once you’ve confirmed the registry works as expected, you should disable the admin account and use Azure Active Directory identities exclusively to ensure the security of your registry.

Azure Container Instance (ACI)
  • Azure Container Instance service can load an image from Azure Container Registry and run it in Azure
  • instance will have an ip address to be accessible
  • dns name can be used for a friendly label
  • image url can be azure container registry or docker hub
  • runs a container in Azure without managing virtual machines and without a higher-level service
  • Fast startup: Launch containers in seconds.
  • Per second billing: Incur costs only while the container is running.
  • Hypervisor-level security: Isolate your application as completely as it would be in a VM.
  • Custom sizes: Specify exact values for CPU cores and memory.
  • Persistent storage: Mount Azure Files shares directly to a container to retrieve and persist state.
  • Linux and Windows: Schedule both Windows and Linux containers using the same API.
  • The ease and speed of deploying containers in Azure Container Instances makes it a great fit for executing run-once tasks like image rendering or building and testing applications.
  • provide a DNS name to expose your container to the Internet (dns must be unique)

For scenarios where you need full container orchestration, including service discovery across multiple containers, automatic scaling, and coordinated application upgrades, we recommend Azure Kubernetes Service (AKS).

Create an Azure Container Instance (ACI)
# Using Azure Container Instance to run a docker image

# use to generate random dns name

# use these image for quick start/ or demo
--image microsoft/aci-helloworld         # -> basic Node.js web application on docker hub
--image microsoft/aci-wordcount:latest   # -> This container runs a Python script that analyzes the text of Shakespeare's Hamlet, writes the 10 most common words to standard output, and then exits

# create a container instance and start the image running
# for a user friendly url -> --dns-name-label mydnsname
az container create --resource-group mygroup --name ecommerceapiproducts --image parisaregistry.azurecr.io/ecommerceapiproducts:latest --os-type Windows --dns-name-label ecommerceapiproducts  --registry-username ":)" --registry-password ":O"

az container create --resource-group mygroup --name myproducts1 --image parisaregistry.azurecr.io/ecommerceapiproducts:latest --os-type Windows  --registry-login-server parisaregistry.azurecr.io --registry-username ":)" --registry-password ":O" --dns-name-label myproducts --ports 9000 --environment-variables 'PORT'='9000'

ACI restart-policies

Azure Container Instances has three restart-policy options [Source]:

Restart policy
in Azure Container Instance
Always in ACIContainers in the container group are always restarted. This policy makes sense for long-running tasks such as a web server.
This is the default setting applied when no restart policy is specified at container creation.
Never in ACIContainers in the container group are never restarted.
The containers run one time only.
OnFailure in ACIContainers in the container group are restarted only when the process executed in the container fails (when it terminates with a nonzero exit code).
The containers are run at least once. This policy works well for containers that run short-lived tasks.

Azure Container Instances starts the container and then stops it when its process (a script, in this case) exits. When Azure Container Instances stops a container whose restart policy is Never or OnFailure, the container’s status is set to Terminated.

az container create \
  --resource-group learn-deploy-aci-rg \
  --name mycontainer-restart-demo \
  --image microsoft/aci-wordcount:latest \
  --restart-policy OnFailure \
  --location eastus

az container show \
  --resource-group learn-deploy-aci-rg \
  --name mycontainer-restart-demo \
  --query containers[0].instanceView.currentState.state

az container logs \
  --resource-group learn-deploy-aci-rg \
  --name mycontainer-restart-demo
ACI check log, state, events
az container delete --resource-group mygroup --name myproducts1

az container logs --resource-group mygroup --name myproducts1

az container attach --resource-group mygroup --name myproducts1

# find the fully qualified domain name of the instance by querying the IP address of the instance or Azure UI > Azure Container Instance > Overview: FQND
az container show --resource-group mygroup --name myproducts --query ipAddress.fqdn

# another variant 
--query "{FQDN:ipAddress.fqdn,ProvisioningState:provisioningState}" \
--out table

# get the status of the container
--query containers[0].instanceView.currentState.state

# Execute a command in your container
az container exec \
  --resource-group learn-deploy-aci-rg \
  --name mycontainer \
  --exec-command /bin/sh

# Monitor CPU and memory usage on your container
CONTAINER_ID=$(az container show \
  --resource-group learn-deploy-aci-rg \
  --name mycontainer \
  --query id \
  --output tsv)

az monitor metrics list \
  --resource $CONTAINER_ID \
  --metric CPUUsage \
  --output table

az monitor metrics list \
  --resource $CONTAINER_ID \
  --metric MemoryUsage \
  --output table

ACI set environment variables [Source]
# create an Azure Cosmos DB name

# create the cosmos db, get endpoint and masterkey
COSMOS_DB_ENDPOINT=$(az cosmosdb create \
  --resource-group learn-deploy-aci-rg \
  --name $COSMOS_DB_NAME \
  --query documentEndpoint \
  --output tsv)

COSMOS_DB_MASTERKEY=$(az cosmosdb keys list \
  --resource-group learn-deploy-aci-rg \
  --name $COSMOS_DB_NAME \
  --query primaryMasterKey \
  --output tsv)

# create a container and set environments variables
az container create \
  --resource-group learn-deploy-aci-rg \
  --name aci-demo \
  --image microsoft/azure-vote-front:cosmosdb \
  --ip-address Public \
  --location eastus \
  --environment-variables \

# get environment variables (by default are plaintext)
az container show \
  --resource-group learn-deploy-aci-rg \
  --name aci-demo \
  --query containers[0].environmentVariables

# secure environment variables to hide
az container create \
  --resource-group learn-deploy-aci-rg \
  --name aci-demo-secure \
  --image microsoft/azure-vote-front:cosmosdb \
  --ip-address Public \
  --location eastus \
  --secure-environment-variables \
ACI data volumes [Source]
  • By default, Azure Container Instances are stateless.
  • If the container crashes or stops, all of its state is lost.
  • To persist state beyond the lifetime of the container, you must mount a volume from an external store.
  • mount an Azure file share to an Azure container instance so you can store data and access it later

az storage account create \
  --resource-group learn-deploy-aci-rg \
  --sku Standard_LRS \
  --location eastus

# AZURE_STORAGE_CONNECTION_STRING is a special environment variable that's understood by the Azure CLI. 
# The export part makes this variable accessible to other CLI commands you'll run shortly.
export AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string \
  --resource-group learn-deploy-aci-rg \
  --output tsv)

# create a file share
az storage share create --name aci-share-demo

# To mount an Azure file share as a volume in Azure Container Instances, you need these three values:
# The storage account name
# The share name
# The storage account access key
STORAGE_KEY=$(az storage account keys list \
  --resource-group learn-deploy-aci-rg \
  --account-name $STORAGE_ACCOUNT_NAME \
  --query "[0].value" \
  --output tsv)

# check the value

# Deploy a container and mount the file share (mount /aci/logs/ to your file share)
az container create \
  --resource-group learn-deploy-aci-rg \
  --name aci-demo-files \
  --image microsoft/aci-hellofiles \
  --location eastus \
  --ports 80 \
  --ip-address Public \
  --azure-file-volume-account-name $STORAGE_ACCOUNT_NAME \
  --azure-file-volume-account-key $STORAGE_KEY \
  --azure-file-volume-share-name aci-share-demo \
  --azure-file-volume-mount-path /aci/logs/

# check the storage
az storage file list -s aci-share-demo -o table

az storage file download -s aci-share-demo -p <filename>


Using Azure APP Service

  • platform as a service (PaaS) 
  • Azure takes care of the infrastructure to run and scale your applications.
  • deployment slots
    • easily add deployment slots to an App Service web app (for creating a staging)
    • swap the staging deployment slot with the production slot
  • Azure portal provides out-of-the-box continuous integration and deployment with Azure DevOps, GitHub, Bitbucket, FTP, or a local Git repository on your development machine


You owe your dreams your courage.

Koleka Putuma

Published by parisamoosavinezhad

- Software Engineer - Software Architect - Software and database specialist - Cloud solution architect

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: