Deploy multiple container apps to Azure with FQDN connections from the Github Container Registry using Container Apps and automate all of it using GitHub Actions. This example deployment and automation used an official guide as a reference.
We are going to setup two containers. Container 1 is a lightweight front end with little bit of JavaScript, HTML, and CSS. Container 2 will be the back end, and it will expose an HTTP API that Container 1 can call.
- Create a Container App named
app1
with a new resource group calleddemo-multiapp
- Create a Container App Environment named
demo-multiapp-env
- Now create another Container App named
app2
reusing the same resource group and App Environment
You can achieve these actions with the Azure CLI as well as the portal:
- Go to
app1
settings and click on Ingress and change the port to8000
- Go to
app2
settings and click on Ingress and change the port to8001
- Change the Ingress Traffic on
app2
to Limited to Container Apps Environment
The access token will need to be added as an Action secret. Create one with enough permissions to write to packages.
You'll need the following:
- An Azure subscription ID find it here or follow this guide
- A Service Principal with the following details the AppID, password, and tenant information. Create one with:
az ad sp create-for-rbac -n "REST API Service Principal"
and assign the IAM role for the subscription. Alternatively set the proper role access using the following command (use a real subscription id and replace it):
az ad sp create-for-rbac --name "CICD" --role contributor --scopes /subscriptions/$AZURE_SUBSCRIPTION_ID --sdk-auth
You must add the resulting JSON value as an Actions Secret with the name of AZURE_CREDENTIALS
Make sure you have one instance already created, and then capture the name and resource group. These will be used in the workflow file.
Make sure you use 2 CPU cores and 4GB of memory per container. Otherwise you may get an error because loading HuggingFace with FastAPI requires significant memory upfront.
There are a few things that might get you into a failed state when deploying:
- Not having enough RAM per container
- Not using authentication for accessing the remote registry (ghcr.io in this case). Authentication is always required
- Not using a PAT (Personal Access Token) or using a PAT that doesn't have write permissions for "packages".
- Different port than 80 in the container. By default Azure Container Apps use 80. Update to match the container.
If running into trouble, check logs in the portal or use the following with the Azure CLI:
az containerapp logs show --name $CONTAINER_APP_NAME --resource-group $RESOURCE_GROUP_NAME --follow
Update both variables to match your environment
Although there are a few best practices for using the FastAPI framework, there are many different other suggestions to build solid HTTP APIs that can be applicable anywhere.
The HTTP specification has several error codes available. Make use of the appropriate error code to match the condition that caused it. For example the 401
HTTP code can be used when access is unauthorized. You shouldn't use a single error code as a catch-all error.
Here are some common scenarios associated with HTTP error codes:
400 Bad request
: Use this to indicate a schema problem. For example if the server expected a string but got an integer401 Unauthorized
: When authentication is required and it wasn't present or satisfied404 Not found
: When the resource doesn't exist
Note that it is a good practice to use 404 Not Found
to protect from requests that try to find if a resource exists without being authenticated. A good example of this is a service that doesn't want to expose usernames unless you are authenticated.
GET | POST | PUT | HEAD |
---|---|---|---|
Read Only | Write Only | Update existing | Does it exist? |