Deploy a Flask or FastAPI web app on Azure Container Apps

This tutorial shows you how to containerize a Python Flask or FastAPI web app and deploy it to Azure Container Apps. Azure Container Apps uses Docker container technology to host both built-in images and custom images. For more information about using containers in Azure, see Comparing Azure container options.

In this tutorial, you use the Docker CLI and the Azure CLI to create a Docker image and deploy it to Azure Container Apps. You can also deploy with Visual Studio Code and the Azure Tools Extension.

Prerequisites

To complete this tutorial, you need:

Get the sample code

In your local environment, get the code.

git clone https://github.com/Azure-Samples/msdocs-python-flask-webapp-quickstart.git

Add Dockerfile and .dockerignore files

Add a Dockerfile to instruct Docker how to build the image. The Dockerfile specifies the use of Gunicorn, a production-level web server that forwards web requests to the Flask and FastAPI frameworks. The ENTRYPOINT and CMD commands instruct Gunicorn to handle requests for the app object.

# syntax=docker/dockerfile:1

FROM python:3.11

WORKDIR /code

COPY requirements.txt .

RUN pip3 install -r requirements.txt

COPY . .

EXPOSE 50505

ENTRYPOINT ["gunicorn", "app:app"]

50505 is used for the container port (internal) in this example, but you can use any free port.

Check the requirements.txt file to make sure it contains gunicorn.

Flask==2.2.2
gunicorn
Werkzeug==2.2.2

Add a .dockerignore file to exclude unnecessary files from the image.

.git*
**/*.pyc
.venv/

Configure gunicorn

Gunicorn can be configured with a gunicorn.conf.py file. When the gunicorn.conf.py file is located in the same directory where gunicorn is run, you don't need to specify its location in the ENTRYPOINT or CMD instruction of the Dockerfile. For more information about specifying the configuration file, see Gunicorn settings.

In this tutorial, the suggested configuration file configures GUnicorn to increase its number of workers based on the number of CPU cores available. For more information about gunicorn.conf.py file settings, see Gunicorn configuration.

# Gunicorn configuration file
import multiprocessing

max_requests = 1000
max_requests_jitter = 50

log_file = "-"

bind = "0.0.0.0:50505"

workers = (multiprocessing.cpu_count() * 2) + 1
threads = workers

timeout = 120

Build and run the image locally

Build the image locally.

docker build --tag flask-demo .

Run the image locally in a Docker container.

docker run --detach --publish 5000:50505 flask-demo

Open the http://localhost:5000 URL in your browser to see the web app running locally.

The --detach option runs the container in the background. The --publish option maps the container port to a port on the host. The host port (external) is first in the pair, and the container port (internal) is second. For more information, see Docker run reference.

Deploy web app to Azure

To deploy the Docker image to Azure Container Apps, use the az containerapp up command. (The following commands are shown for the Bash shell. Change the continuation character (\) as appropriate for other shells.)

az containerapp up \
  --resource-group web-flask-aca-rg --name web-aca-app \
  --ingress external --target-port 50505 --source .

When deployment completes, you have a resource group with the following resources inside of it:

  • An Azure Container Registry
  • A Container Apps Environment
  • A Container App running the web app image
  • A Log Analytics workspace

The URL for the deployed app is in the output of the az containerapp up command. Open the URL in your browser to see the web app running in Azure. The form of the URL will look like the following https://web-aca-app.<generated-text>.<location-info>.azurecontainerapps.io, where the <generated-text> and <location-info> are unique to your deployment.

Make updates and redeploy

After you make code updates, you can run the previous az containerapp up command again, which rebuilds the image and redeploys it to Azure Container Apps. Running the command again takes in account that the resource group and app already exist, and updates just the container app.

In more complex update scenarios, you can redeploy with the az acr build and az containerapp update commands together to update the container app.

Clean up

All the Azure resources created in this tutorial are in the same resource group. Removing the resource group removes all resources in the resource group and is the fastest way to remove all Azure resources used for your app.

To remove resources, use the az group delete command.

az group delete --name web-flask-aca-rg

You can also remove the group in the Azure portal or in Visual Studio Code and the Azure Tools Extension.

Next steps

For more information, see the following resources: