Deploy A Flask REST API to Azure App Service using Docker
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
andDocker 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 :v1
to 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.