# Create the container image
docker build --platform linux/amd64 -t shuffereu/dfas-ai-webapp:v2 .
# Run the container locally
docker run -it --platform linux/amd64 -p 8000:8000 shuffereu/dfas-ai-webapp:v2
# Push the container image to docker hub
docker push shuffereu/dfas-ai-webapp:v2
# Create the webapp in azure
az webapp create --resource-group dfas2 --plan dfas2asp --name dfas2-webapp --deployment-container-image-name shuffereu/dfas-ai-webapp:v2
# Create the ACR
az acr create --resource-group <your-resource-group> --name <your-acr-name> --sku Basic
# Push the container image to ACR
# Log in to ACR
az acr login --name <your-acr-name>
# Tag the image for the ACR repository
docker tag <your-image-name>:v1 <your-acr-name>.azurecr.io/<your-image-name>:v1
# Push the image to ACR
docker push <your-acr-name>.azurecr.io/<your-image-name>:v1
## Grant Azure Container APp Access to ACR
az acr update --name --resource-group --admin-enabled true
## Create a Managed Idneitty for ACA and assign the AcrPull role to the ideneity so it can pull from ACR
az role assignment create --assignee dfas-acr-pull-role --role AcrPull --scope $(az acr show --name reubenc --query id --output tsv)
## Create an ACR using UID/PWD
az container create
--resource-group dfas2
--name dfas-ai-webapp
--image reubenc.azurecr.io/dfas-ai-webapp:v2
--registry-login-server reubenc.azurecr.io
--registry-username reubenc
--ports 8000
--registry-password xxx+xxx
--cpu 1 --memory 1
--dns-name-label dfasaiwebapp -o table
Create a resource group named dfas2 in your desired location (e.g., eastus):
az group create --name dfas2 --location eastus --output tsvCreate an App Service plan named dfas-asp:
az appservice plan create \
--name dfas-asp \
--resource-group dfas2 \
--is-linux \
--sku B1 \
--output tsvNote: B1 is the Basic pricing tier. Modify the SKU to suit your needs if needed.
Create the WebApp that will use the container from ACR and assign a system-managed identity:
# **Important Note**: At this point, the WebApp may not be able to pull the container image from the Azure Container Registry (ACR) because the managed identity does not yet have the required `AcrPull` permission. The container deployment might fail initially, but this is resolved after assigning the `AcrPull` role in the next step.
# Create the WebApp
az webapp create \
--resource-group dfas2 \
--plan dfas-asp \
--name dfas2-webapp \
--deployment-container-image-name reubenc.azurecr.io/dfas-ai-webapp:v3 \
--output tsv
# Assign a system-managed identity to the WebApp
az webapp identity assign --resource-group dfas2 --name dfas2-webapp --output tsvThe system-assigned managed identity of the WebApp will need permission to pull the Docker container image from Azure Container Registry (ACR). To do this, assign the AcrPull role after creating the WebApp:
# Retrieve ACR resource ID
acr_id=$(az acr show --resource-group aoai --name reubenc --query "id" --output tsv)
# Retrieve the principal ID of the managed identity of the WebApp
identity_principal_id=$(az webapp identity show --resource-group dfas2 --name dfas2-webapp --query "principalId" --output tsv)
# Grant AcrPull permission for the managed identity
az role assignment create --assignee $identity_principal_id --scope $acr_id --role AcrPull --output tsvSet the necessary app settings so that the WebApp runs on port 8000:
az webapp config appsettings set \
--resource-group dfas2 \
--name dfas2-webapp \
--settings WEBSITES_PORT=8000 \
--output tsvIf you want to create an Azure Function App, you can do so with the following commands:
# Create a storage account for the Function App
az storage account create \
--name dfas2funcstorage \
--resource-group dfas2 \
--location eastus \
--sku Standard_LRS \
--output tsv
# Create the Function App
az functionapp create \
--resource-group dfas2 \
--consumption-plan-location eastus \
--name dfas2-functionapp \
--storage-account dfas2funcstorage \
--runtime python \
--functions-version 4 \
--output tsvTo ensure everything is working correctly, use the following validation steps:
-
Verify WebApp Status:
az webapp show --resource-group dfas2 --name dfas2-webapp --query "state" --output tsvEnsure that the state is
Running. -
Verify that the WebApp is accessible: Open the WebApp URL in a browser or use
curlto make sure it is responding:curl http://dfas2-webapp.azurewebsites.net
-
Verify that the Managed Identity has AcrPull Role:
az role assignment list --assignee $identity_principal_id --scope $acr_id --query "[?roleDefinitionName=='AcrPull']" --output tsv
Ensure that the output is not empty, confirming the role assignment.
If the container still fails to start, try the following:
-
Check App Logs:
az webapp log tail --name dfas2-webapp --resource-group dfas2 --output tsv
This can help identify missing dependencies or configuration issues.
-
Restart the WebApp:
az webapp restart --name dfas2-webapp --resource-group dfas2 --output tsv
If you need to update the container image used by the WebApp (for example, to deploy a new version of your application), you can use the following command to change the container image:
# Update the WebApp to use a different version of the container image
az webapp config container set \
--resource-group dfas2 \
--name dfas2-webapp \
--docker-custom-image-name reubenc.azurecr.io/dfas-ai-webapp:v4 \
--output tsvNote: Replace
v4with the appropriate tag for the new version of your container image.
Following these steps will create, deploy, and configure all necessary resources in Azure, ensuring that your FastAPI WebApp is up and running.
Below, I'll provide step-by-step Azure CLI commands to set up an Azure Function App as a container. The container image will be pulled from Azure Container Registry (ACR). We will assume the container image is named dfas-ai-funcs.
NOTE:
Function App can be co-hosted on the same App Service Plan as the WebApp, but only if both meet specific compatibility requirements:
-
Linux Requirement: Both the WebApp and Function App need to be hosted in a Linux-based App Service Plan. In your case, the App Service Plan (dfas-asp) was created as a Linux plan (--is-linux), which makes it compatible for co-hosting both a WebApp and Function App container.
-
Elastic Premium Plan: Azure Function Apps require an Elastic Premium (EP) or App Service Plan when using custom Docker containers. You would need at least a Premium v2 plan (such as P1v2) to support Function Apps as containers.
Commands to Co-host the Function App: If you decide to use the same App Service Plan, the Function App can be created using the existing plan (dfas-asp) with a modified command:
# Create the Function App using the existing App Service Plan
az functionapp create \
--resource-group dfas2 \
--plan dfas-asp \ # Use the existing plan
--name dfas2-functionapp \
--storage-account dfasfuncstorage \
--deployment-container-image-name reubenc.azurecr.io/dfas-ai-funcs:v1 \
--functions-version 4 \
--os-type Linux \
--output tsv
Create a dedicated Function App Plan to host the Azure Function App. This will allow the Function App to use Linux containers:
az functionapp plan create \
--resource-group dfas2 \
--name dfas-func-plan \
--location eastus \
--number-of-workers 1 \
--sku EP1 \
--is-linux \
--output tsvNote: The SKU
EP1refers to the Elastic Premium tier, which allows the use of custom containers.
Azure Function Apps require a storage account to store triggers and other state information:
az storage account create \
--name dfasfuncstorage \
--resource-group dfas2 \
--location eastus \
--sku Standard_LRS \
--output tsvCreate the Function App and configure it to use the container image from ACR:
# Create the Function App with a container image
az functionapp create \
--resource-group dfas2 \
--plan dfas-func-plan \
--name dfas2-functionapp \
--storage-account dfasfuncstorage \
--deployment-container-image-name reubenc.azurecr.io/dfas-ai-funcs:v1 \
--functions-version 4 \
--os-type Linux \
--output tsvNote: Replace
v1with the appropriate tag for the container image you want to use.
The Function App's managed identity will need permission to pull the Docker container image from ACR. Assign the AcrPull role to the Function App's identity:
# Assign AcrPull role for Function App to access ACR
identity_principal_id=$(az functionapp identity assign --resource-group dfas2 --name dfas2-functionapp --output tsv --query principalId)
# Grant AcrPull permission for the managed identity
az role assignment create --assignee $identity_principal_id --scope $acr_id --role AcrPull --output tsvTo ensure everything is working correctly, use the following validation steps:
-
Verify Function App Status:
az functionapp show --resource-group dfas2 --name dfas2-functionapp --query "state" --output tsvEnsure that the state is
Running. -
Verify Logs: Use the following command to view live logs and ensure the function is running properly:
az functionapp log tail --name dfas2-functionapp --resource-group dfas2 --output tsv