Publishing multi-container application via docker compose in Azure

Goal:

The goal is to take a standard docker-compose file that works on a local docker instance and have it run in Azure. This general write-up assumes you have a docker-compose file that is pulling images from a private azure container registry. The Microsoft documentation on how to push your images to the registry and modify your docker-compose to pull from them is good. The Microsoft tutorial Deploy a multi-container group using Docker Compose is very helpful for creating a registry, pushing your images, and modifying your docker-compose file. From the section on creating an Azure context and beyond it doesn't appear to be a good guide for actually running applications in Azure.

The Azure ACI commands work to push images to a private container registery but they do not create a useful containerized application as they shut down since there are no active running tasks. That means trying azure container groups which have a reset policy. Something Azure seems to care deeply about.

For containerapps, you have to piece it together from their documentation.

https://learn.microsoft.com/en-us/cli/azure/containerapp/compose?view=azure-cli-latest

Spin up your containers

az containerapp compose

Prerequisites:

* You need a resource group created

1. Register the app

az provider register -n Microsoft.App --wait

2. Create the containerapp

az containerapp compose create -g muserdemo --environment muserdocker --compose-file-path ./docker-compose.yml

This will put the containers up and start them but will complain that the azure file storage mount setup in docker compose is invalid with containerapps. So you then have to mount storage in a separate method. In the older ACI documentation the docker-compose mounts work great, but not with container apps.

Setting Up Storage

Storage Commands - https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli

and a tutorial that I found very helpful - https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts-azure-files?tabs=bash

3. Setup environment variables for the next commands

RESOURCE_GROUP="muserdemo"

ENVIRONMENT_NAME="muserdemo-storage-environment"

LOCATION="West US 2"

4. Make sure the latest az extensions are loaded on your box

az extension add -n containerapp --upgrade

5. Register the namespace

az provider register --namespace Microsoft.App

6. Register the OperationalInsights

az provider register --namespace Microsoft.OperationalInsights

7. One more environment variable before creating the storage account

STORAGE_ACCOUNT_NAME="mymuserdemostorageacct$RANDOM"

az storage account create --resource-group $RESOURCE_GROUP --name $STORAGE_ACCOUNT_NAME --location "$LOCATION" --kind StorageV2 --sku Standard_LRS --enable-large-file-share --query provisioningState

8. More environment variables

STORAGE_SHARE_NAME="muserwebdata"

9. Create the volume share

az storage share-rm create --resource-group $RESOURCE_GROUP --storage-account $STORAGE_ACCOUNT_NAME --name $STORAGE_SHARE_NAME --quota 1024 --enabled-protocols SMB --output table

10. Create environment varaiables and then link the storage to the container

ENVIRONMENT_NAME="muserdocker"

STORAGE_ACCOUNT_KEY=`az storage account keys list -n $STORAGE_ACCOUNT_NAME --query "[0].value" -o tsv`

az containerapp env storage set --access-mode ReadWrite --azure-file-account-name $STORAGE_ACCOUNT_NAME --azure-file-account-key $STORAGE_ACCOUNT_KEY --azure-file-share-name $STORAGE_SHARE_NAME --storage-name $STORAGE_MOUNT_NAME --name $ENVIRONMENT_NAME --resource-group $RESOURCE_GROUP --output table

11. Export the config of the container to yaml to work with az container commands

az containerapp show --name apache --resource-group muserdemo --output yaml > app.yaml

I renamed app.yaml as apache-app.yaml for updating the config as I also have a php container and mariadb container.

You end up modifying the exported yaml file to tell it where the storage that you created above resides. You have to do this for each container that you want persistent storage. For my use case, I could use the same storage for my PHP and Apache containers but needed to make a new mount for MariaDB.

12. Set another environment variable for the command to update your container

CONTAINER_APP_NAME="apache"

az containerapp update --name $CONTAINER_APP_NAME --resource-group $RESOURCE_GROUP --yaml app.yaml --output table

13. Login via docker exec and verify the container is mounted as you expect

az containerapp exec --name $CONTAINER_APP_NAME --resource-group $RESOURCE_GROUP

 

 

Tags

Blog Type