- read

A Simple Guide to Deploying a Dockerized Python app to Azure

Bjørnar Kjenaas Mælum 78

So you are telling me you have built an app and now you want to deploy it for everyone to see? Look no further. Here is how to deploy it on Azure using Docker, Azure Container Registry and Azure Container Instances.

This guide uses a FastAPI app as the example app and assumes you are familiar with the basics of using the terminal, building a Python application and basic Docker commands. If you have an app of your own that you want to deploy to Azure the only thing you need is to Dockerize the app using a suitable Dockerfile that matches your app.

What will you have achieved after finishing this guide? Well, you’ll have a deployed version of your app on Azure. Great, right?

1. Setup your app

First, let’s set up a working FastAPI app we can deploy to Azure. I will be using a simple Hello World example you can find here: https://github.com/bmaelum/fastapi-hello-world

The app contains a main file in the /app folder, this is where the FastAPI code is found.

from fastapi import FastAPI app = FastAPI(
title="FastAPI - Hello World",
description="This is the Hello World of FastAPI.",
version="1.0.0",)
@app.get("/")
def hello_world():
return {"Hello": "World"}

To use app, first fork the repository to create a copy in your own Github account. This is necessary to complete the steps using Github Actions. If you want to use the example code for this guide fork the repo by going to this URL: https://github.com/bmaelum/fastapi-hello-world and click the “Fork” button.

To be able to test the code, clone the repo to your machine:

git clone [email protected]:<your-username>/fastapi-hello-world.git

Then install the requirements found in the requirements.txt file into your environment:

pip install -r requirements.txt

To run the app, simply type:

uvicorn app.main:app

You should see something like this in the terminal:

INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Testing the app can be done in the browser or with a tool like Postman. To check out the app in your browser simply go to the URL printed in the terminal, in this case: http://127.0.0.1:8000.

2. It’s time to Dockerize

Now, let’s Dockerize the application.

Photo by Ian Taylor on Unsplash

Using Docker to deploy your app is great for many reasons, one of them is that it helps you make sure you have the same environment for your local development as for the deployment on Azure.

Make sure you have a suitable Dockerfile. In the example file the Dockerfile looks like this:

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7 COPY ./app /app COPY requirements.txt .
RUN pip --no-cache-dir install -r requirements.txt

2.1 Build Docker image

To build the Docker image simply run:

docker build -t fastapi-image .

2.2 Run and test the Docker image

To run the image in a container, simply run:

docker run -p 80:80 -it fastapi-image

To test the app you can use the same address as before, just change the port to 80, like this: http://127.0.0.1:80.

Your app works locally, great! Now it’s time to deploy it to Azure!

3. Let’s deploy the app to Azure

Ready to deploy to Azure? Exciting!

Deploying the app to Azure requires us doing a few actions in the Azure portal as well as using Github Actions.

This guide will now be following the official documentation of Microsoft found here: https://docs.microsoft.com/en-us/azure/container-instances/container-instances-github-action

3.1 Resource group and Service Principal

Firstly we need to create a Service Principal, a role, in the desired resource group. If you don’t already have a resource group simply create one by going to Resource groups in the Azure portal.

To create a Service Principal we are using Bash in the Azure Cloud Shell. Open this by clicking on the Cloud Shell icon on the top of the page:

The Azure Cloud Shell icon

Make sure it is set to Bash in the top left of the Cloud Shell:

Bash when using Cloud Shell in the Azure portal

Then, create a Service Principal for the Resource Group in Azure by using the following command and give the role a name and the scope is the Resource ID for your Resource Group.

Get the Resource Group ID:

groupId=$(az group show \
--name <resource-group-name> \
--query id --output tsv)

Create the role:

az ad sp create-for-rbac \
--name githubactions \
--scope $groupId \
--role Contributor \
--sdk-auth

This will give you a JSON in this format:

{
"clientId": "",
"clientSecret": "",
"subscriptionId": "",
"tenantId": "",
"activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
"resourceManagerEndpointUrl": "https://management.azure.com/",
"activeDirectoryGraphResourceId": "https://graph.windows.net/",
"sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
"galleryEndpointUrl": "https://gallery.azure.com/",
"managementEndpointUrl": "https://management.core.windows.net/"
}

Make sure to save this as it will be used to authenticate when using Github Actions.

4. Create Container Registry

To manage a Docker container and images you need to create a Container Registry within Azure.

Search for “Container registries” and choose “Create”. Choose your resource group, a name for the instance and a location. For SKU you can choose the Basic option.

5. Ready for Github Actions and Azure Container Instances?

Great, let’s get going with the setup of Github Actions.

Remember the JSON you collected in the previous step? Now it’s time to use it.

Go to Github and the repository containing your app. Then go to Settings -> Secrets and add the following credentials(official docs):

AZURE_CREDENTIALSThe entire JSON output from the service principal creation step

REGISTRY_LOGIN_SERVERThe login server name of your registry (all lowercase). Example: myregistry.azurecr.io

REGISTRY_USERNAMEThe clientId from the JSON output from the service principal creation

REGISTRY_PASSWORDThe clientSecret from the JSON output from the service principal creation

RESOURCE_GROUPThe name of the resource group you used to scope the service principal

6. Set up the workflow in Github Actions

Now, let’s setup the workflow using Github Actions. Firstly, go to your repo on Github and click the “Actions” button. From there, choose “Skip this and set up a workflow yourself”.

Get started with Github Actions

Replace the existing code in the main.yml file with the following code:

on: [push]
name: PythonAppAzureDeployment
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# checkout the repo
- name: 'Checkout GitHub Action'
uses: actions/[email protected]

- name: 'Login via Azure CLI'
uses: azure/[email protected]
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: 'Build and push image'
uses: azure/[email protected]
with:
login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- run: |
docker build . -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/sampleapp:${{ github.sha }}
docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/sampleapp:${{ github.sha }}

- name: 'Deploy to Azure Container Instances'
uses: 'azure/[email protected]'
with:
resource-group: ${{ secrets.RESOURCE_GROUP }}
dns-name-label: ${{ secrets.RESOURCE_GROUP }}${{ github.run_number }}
image: ${{ secrets.REGISTRY_LOGIN_SERVER }}/sampleapp:${{ github.sha }}
registry-login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
registry-username: ${{ secrets.REGISTRY_USERNAME }}
registry-password: ${{ secrets.REGISTRY_PASSWORD }}
name: fastapi-sampleapp
location: 'west europe'

Then, commit the file and because we have specified “on: push” it will run straight away. If it doesn’t make sure the code has been commited and pushed to the repo.

Now, wait for the code to be built and deployed. You can follow the progress by clicking “Actions” and choosing the running pipeline.

If you get the error:

Error: The subscription is not registered to use namespace ‘Microsoft.ContainerInstance’.

Simply do the following in PowerShell:

Register-AzResourceProvider -ProviderNamespace Microsoft.ContainerInstance

Alternatively, in Azure, you can go to “Subscriptions”, choose your subscription, go to Resource Providers, search for “ContainerInstance”, click the desired result and click “Register”.

7. Azure Container Instances

Your Dockerized app should now be visible when going to the Container Instances in the Azure portal.

Azure Container Instances

Test the app

To test the app click on the newly deployed Container Instance and go to Properties. Under FQDN there is a URL. Paste the URL in your browser and you should see something like this:

Testing the deployed app in the browser

Congratulations, you have now deployed a Dockerized app on Azure!

Photo by bruce mars on Unsplash