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
  • Azure Kubernetes Service
  • Using Azure APP Service
  • background task in an App Service Web App with WebJobs

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 aplication 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>


Azure Kubernetes Service

  • The task of automating, managing, and interacting with a large number of containers is known as orchestration.
  • Azure Kubernetes Service (AKS) is a complete orchestration service for containers with distributed architectures with multiple containers.
  • You can move existing applications to containers and run them within AKS.
  • You can control access via integration with Azure Active Directory (Azure AD) and access Service Level Agreement (SLA)–backed Azure services, such as Azure Database for MySQL for any data needs, via Open Service Broker for Azure (OSBA).


Using Azure APP Service

  • platform as a service (PaaS) 
  • Azure takes care of the infrastructure to run and scale your applications.
  • prerequisite is a staging deployment slot to push code to azure app service
    • 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
  • Mode : Free doesn’t support deployment slot
Seployment slopts are listed under “Deployment slots” menu
  • Continuous integration/deployment support
    • Connect your web app with any of the above sources and App Service will do the rest for you by automatically syncing your code and any future changes on the code into the web app
    • with Azure DevOps, you can define your own build and release process that compiles your source code, runs the tests, builds a release, and finally deploys the release into your web app every time you commit the code
out-of-the-box continuous integration and deployment

Automated deployment

Automated deployment, or continuous integration, is a process used to push out new features and bug fixes in a fast and repetitive pattern with minimal impact on end users.

Azure supports automated deployment directly from several sources. The following options are available:

  • Azure DevOps: You can push your code to Azure DevOps (previously known as Visual Studio Team Services), build your code in the cloud, run the tests, generate a release from the code, and finally, push your code to an Azure Web App.
  • GitHub: Azure supports automated deployment directly from GitHub. When you connect your GitHub repository to Azure for automated deployment, any changes you push to your production branch on GitHub will be automatically deployed for you.
  • Bitbucket: With its similarities to GitHub, you can configure an automated deployment with Bitbucket.
  • OneDrive: Microsoft’s cloud-based storage. You must have a Microsoft Account linked to a OneDrive account to deploy to Azure.
  • Dropbox: Azure supports deployment from Dropbox, which is a popular cloud-based storage system that is similar to OneDrive.

Manual deployment

There are a few options that you can use to manually push your code to Azure:

  • Git: App Service web apps feature a Git URL that you can add as a remote repository. Pushing to the remote repository will deploy your app.
  • az webapp upwebapp up is a feature of the az command-line interface that packages your app and deploys it. Unlike other deployment methods, az webapp up can create a new App Service web app for you if you haven’t already created one.
  • Zipdeploy: Use az webapp deployment source config-zip to send a ZIP of your application files to App Service. Zipdeploy can also be accessed via basic HTTP utilities such as curl.
  • Visual Studio: Visual Studio features an App Service deployment wizard that can walk you through the deployment process.
  • FTP/S: FTP or FTPS is a traditional way of pushing your code to many hosting environments, including App Service.
# using SDK version 3.1.102. 
wget -q -O - https://dot.net/v1/dotnet-install.sh | bash -s -- --version 3.1.102
export PATH="~/.dotnet:$PATH"
echo "export PATH=~/.dotnet:\$PATH" >> ~/.bashrc

# create a new ASP.NET Core MVC application
dotnet new mvc --name BestBikeApp

# build and run the application to verify it is complete.
cd BestBikeApp
dotnet run
# output
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /home/user/BestBikeApp

# Deploy with zipdeploy
dotnet publish -o pub
cd pub
zip -r site.zip *

# perform the deployment
az webapp deployment source config-zip \
    --src site.zip \
    --resource-group learn-6126217c-08a6-4509-a288-2941d4b96a27 \
    --name <your-unique-app-name>


background task in an App Service Web App with WebJobs

  • Automate a task for a Web App that should run in the background without affecting the performance of the Web App
  • small automated task, which executes automatically in response to some events

Scenario: Suppose you are a senior web developer in a research role for an online luxury watch dealer. You have a production website that uses Azure web apps. You’ve built a small script that checks stock levels and reports them to an external service. You consider this script to be part of the website, but it’s meant to run in the background, not in response to a user’s actions on the site.

You’d like the website and the script code to be closely associated. They should be stored together as part of the same project in the same source control repository. The script may grow and change as the site changes, so you’d like to always deploy them at the same time, to the same set of cloud resources.

  • WebJobs are a feature of Azure App Service
  • WebJobs can be used to run any script or console application that can be run on a Windows computer, with some functionality limitations
  • To run a WebJob, you’ll need an existing Azure App Service web app, web API, or mobile app
  • You can run multiple WebJobs in a single App Service plan along with multiple apps or APIs.
  • Your WebJobs can be written as scripts of several different kinds including Windows batch files, PowerShell scripts, or Bash shell scripts
  • You can upload such scripts and executables directly to the web app in the Azure portal
  • you can write WebJobs using a framework such as Python or Node.js
  • This approach enables you to use the WebJobs tools in Visual Studio to ease development.

Types of Webjob

it starts when it is deployedonly starts when scheduled or manually triggered
continues to run in an endless loop
for continuous the code must be written in loop (to poll a message queue for new items and process their contents)use this kind of WebJob, for example, to create daily summaries of messages in a queue.

Webjob vs. Azure function (to know more about Azure Serverless Services/Architecture)


You owe your dreams your courage.

Koleka Putuma

Published by parisamoosavinezhad

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

One thought on “Onboarding : Modern Applications

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 )

Facebook photo

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

Connecting to %s

%d bloggers like this: