Overview: Deploy a Python web app on Azure Container Apps
This tutorial shows you how to containerize a Python web app and deploy it to Azure Container Apps. A sample web app is containerized and the Docker image stored in Azure Container Registry. Azure Container Apps is configured to pull the Docker image from Container Registry and create a container. The sample app connects to an Azure Database for PostgreSQL to demonstrate communication between Container Apps and other Azure resources.
There are several options to build and deploy cloud native and containerized Python web apps on Azure. This tutorial covers Azure Container Apps. Container Apps are good for running general purpose containers, especially for applications that span many microservices deployed in containers. In this tutorial, you create one container. To deploy a Python web app as a container to Azure App Service, see Containerized Python web app on App Service.
In this tutorial you'll:
- Build a Docker image from a Python web app and store the image in Azure Container Registry.
- Configure Azure Container Apps to host the Docker image.
- Set up a GitHub Action that updates the container with a new Docker image triggered by changes to your GitHub repository. This last step is optional.
Following this tutorial, you're set up for Continuous Integration (CI) and Continuous Deployment (CD) of a Python web app to Azure.
Service overview
The service diagram supporting this tutorial shows how your local environment, GitHub repositories, and Azure services are used in the tutorial.
The components supporting this tutorial and shown in the diagram are:
-
- Azure Container Apps enables you to run microservices and containerized applications on a serverless platform. A serverless platform means that you enjoy the benefits of running containers with minimal configuration. With Azure Container Apps, your applications can dynamically scale based on characteristics such as HTTP traffic, event-driven processing, or CPU or memory load.
- Container Apps pulls Docker images from Azure Container Registry. Changes to container images trigger an update to the deployed container. You can also configure GitHub Actions to trigger updates.
-
- Azure Container Registry enables you to work with Docker images in Azure. Because Container Registry is close to your deployments in Azure, you have control over access, making it possible to use your Microsoft Entra groups and permissions to control access to Docker images.
- In this tutorial, the registry source is Azure Container Registry, but you can also use Docker Hub or a private registry with minor modifications.
-
- The sample code stores application data in a PostgreSQL database.
- The container app connects to PostgreSQL with a user-assigned managed identity. Connection information is stored in environment variables configured explicitly or with Azure Service Connector.
-
- The sample code for this tutorial is in a GitHub repo that you fork and clone locally. To set up a CI/CD workflow with GitHub Actions, you need a GitHub account.
- You can still follow along with this tutorial without a GitHub account, working locally or in the Azure Cloud Shell to build the container image from the sample code repo.
Revisions and CI/CD
To make code changes and push them to a container, you create a new Docker image with your change. Then, you push the image to Container Registry and create a new revision of the container app.
To automate this process, an optional step in the tutorial shows you how to build a continuous integration and continuous delivery (CI/CD) pipeline with GitHub Actions. The pipeline automatically builds and deploys your code to the Container App whenever a new commit is pushed to your GitHub repository.
Authentication and security
In this tutorial, you build a Docker container image directly in Azure and deploy it to Azure Container Apps. Container Apps run in the context of an environment, which is supported by an Azure Virtual Networks (VNet). VNets are a fundamental building block for your private network in Azure. Container Apps allows you to expose your container app to the public web by enabling ingress.
To set up continuous integration and continuous delivery (CI/CD), you authorize Azure Container Apps as an OAuth App for your GitHub account. As an OAuth App, Container Apps writes a GitHub Actions workflow file to your repo with information about Azure resources and jobs to update them. The workflow updates Azure resources using credentials of a Microsoft Entra service principal (or existing one) with role-based access for Container Apps and username and password for Azure Container Registry. Credentials are stored securely in your GitHub repo.
Finally, the tutorial sample web app stores data in a PostgreSQL database. The sample code connects to PostgreSQL via a connection string. When running in Azure, the app connects to the PostgreSQL database with a user-assigned managed identity. The code uses DefaultAzureCredential
to dynamically update the password in the connection string with a Microsoft Entra access token during runtime. This mechanism prevents having to hardcode the password in the connection string or an environment variable and provides an extra layer of security. The tutorial walks you through creating the managed identity and granting it an appropriate PostgreSQL ROLE and permissions for it to access and update the database. During the configuration of the Container App, the tutorial walks you through configuring the managed identity on the app and setting up environment variables containing connection information for the database. You can also use an Azure Service Connector to accomplish the same thing.
Prerequisites
To complete this tutorial, you need:
An Azure account where you can create:
- Azure Container Registry
- Azure Container Apps environment
- Azure Database for PostgreSQL
Visual Studio Code or Azure CLI, depending on what tool you use
- For Visual Studio Code, you need the Container Apps extension.
- You can also use Azure CLI through the Azure Cloud Shell.
Python packages:
- pyscopg2-binary for connecting to PostgreSQL.
- Flask or Django web framework.
Sample app
The Python sample app is a restaurant review app that saves restaurant and review data in PostgreSQL. At the end of the tutorial, you have a restaurant review app deployed and running in Azure Container Apps that looks like the following screenshot.