Deploy A Flask REST API to Azure App Service using Docker

Subhadip Maji
Analytics Vidhya
Published in
4 min readAug 25, 2021

In this tutorial I am going to talk about deploying a Flask application to Azure App Service using Docker. The prerequisites of this blogs are:

  • Python
  • Flask
  • Docker (Concepts of Dockerfile and Docker Compose)
  • Some concepts of Azure Resources e.g. Azure App Service, Azure Container Registry, Azure Resource Group, etc

A sample flask REST API built with Dockerfile and docker-compose can be found here. I shall be doing all the steps from terminal as it would be useful for CICD implementation of a project. Although, I am using macOS, I think Ubuntu (or any other Linux) users can use the same commands. I have tried to make this tutorial very compact. Below are the steps.

Build and Test

Build and test the application by building docker image and running the same. Navigate to your project repository and run,

$ docker compose build
$ docker compose up

Install Azure CLI

This built docker image needs to be pushed to Azure container registry and Azure app Service will pick this image and run as a service. Therefore, to interact with azure Azure CLI needs to be installed.

$ brew update && brew install azure-cli
$ az login

Create Azure Resource Group

To perform anything in Azure, one resource group is required. Azure App Service, Azure Container Registry, Azure Kubernetes, Azure SQL Database, etc, are the components of a resource group. Components from one resource group can communicate with components from another resource group. For this project, you need to first create a resource group and then within this resource group Azure Container Registry and Azure App Service need to be created. To create a resource group in Azure run the following command,

$ az group create -l westus -n [ResourceGroupName]

[ResourceGroupName] is to be replaced with the chosen resource group name. For example, if the chosen resource group is my_azure_group, then the above command will be, $ az group create -l westus -n my_azure_group.

Create Azure Container Registry (ACR)

$ az acr create --resource-group [ResourceGroupName] --name [ACRName] --sku Basic 
$ az acr login --name [ACRName]

The first will create an ACR with the provided name and the second line will ask for the login for authentication.

Push Local Docker Image to ACR

To see a list of current local images, use the docker images command:
$ docker images

The above command’s output shows list of the current local images:

REPOSITORY    TAG         IMAGE ID           CREATED           SIZE
[AppName] latest 34e1853337c2 7 minutes ago 1.24GB

To use the [AppName] container image with ACR, the image needs to be tagged with the login server address of our registry. This tag is used for routing when pushing container images to an image registry.

To get the login server address, use the az acr list command and query for the loginServer as follows:

$ az acr list --resource-group [ResourceGroupName] --query "[].{acrLoginServer:loginServer}" --output table

This will give the following output: [AppName].azurecr.io.Now, tag the local [AppName]image with the acrLoginServer address, [AppName].azurecr.io of the container registry. To indicate the image version, add :v1to the end of the image name:

$ docker tag [AppName]:latest [AppName].azurecr.io/[AppName]:v1

To verify the tags are applied, run docker images again. An image is tagged with the ACR instance address and a version number.

With the image built and tagged, push the [AppName].azurecr.io/[AppName] image to the ACR instance. Use docker push and provide acrLoginServer address for the image name as follows:

$ docker push [AppName].azurecr.io/[AppName]:v1

Create an App Service

To create an app service, one app service plan needs to be created.

$ az appservice plan create --name [PlanName] --resource-group  [ResourceGroupName] --is-linux$ az webapp create --resource-group [ResourceGroupName] --plan [PlanName] --name [AppName] --deployment-container-image-name [AppName].azurecr.io/[AppName]:latest

Set up Port

$ az webapp config appsettings set --resource-group [ResourceGroupName] --name [AppName] --settings WEBSITES_PORT=80

Enable Managed Identity and Retrieve Principal ID

az webapp identity assign --resource-group [ResourceGroupName] --name [AppName] --query principalId --output tsv

Retrieve subscription ID

az account show --query id --output tsv

Grant web app permission to access the container registry

Put principal ID and subscription ID in the below command which are retrieved from the above two commands. The following command is required for continuous deployment.

$ az role assignment create --assignee [PrincipalID] --scope  /subscriptions/[SubscriptionID]/resourceGroups/[ResourceGroupName]/providers/Microsoft.ContainerRegistry/registries/[AppName] --role "AcrPull"

Deploy the container image

$ az webapp config container set --name [AppName] --resource-group [ResourceGroupName] --docker-custom-image-name [AppName].azurecr.io/[AppName]:latest --docker-registry-server-url https://[AppName].azurecr.io

Once deployed the application can be accessed from an unauthenticated URL,[AppName].azurewebsites.net. You can use Postman to for API request in this URL.

The END

So, this is the end of this article, but the start of this series. Comment below for any issue or suggestions. Thank you.

--

--

Subhadip Maji
Analytics Vidhya

Subhadip is a Research Scientist at Amazon. He has done his B.E from Jadavpur University and M.Tech from Indian Statistical Institute, Kolkata.