Drupal on Azure Container App

26 September 2025

Drupal 11 (plus a few security modules) and its dependencies deployed with Docker & Terraform (code on Github) to Azure Container App.

Dependencies include:

  • Azure Container App (0.5 CPU core, 1Gi memory)
  • Azure DB for PostgreSQL flexible server (Burstable Standard_B1ms)
  • Azure Container Registry (Edit: I've since switched to Docker Hub for the cost savings.)
  • Azure User Assigned Identity
  • Azure Key Vault
  • Azure Storage Account File Share - for Drupal's persistent storage
  • init_container to idempotently pre-populate the Drupal file share if necessary
  • Azure DNS Zone CNAME + TXT verification record Azure Container App managed SSL certificate

The trickiest part was managing Drupal's persistent storage. Drupal expects certain content in /var/www/html/sites/, like default_settings.php, it then creates a settings.php when you run through the initial setup wizard, so if I just mounted an empty file share there directly it would hide the expected contents from Drupal and cause errors, and if I mounted Drupal's persistent storage at a deeper directory, the settings.php would be ephemeral, and Drupal would repeatedly fall back to the initial setup wizard.

The solution was to use an init_container that mounts the file share at a different mount point, and if it's not already initialized, it copies the default files into the file share so that it will have the files it needs, and they will be persistent rather than ephemeral:

command = ["/bin/sh", "-c", <<-EOT
  if [ ! -f /mnt/drupal-sites/default/settings.php ]; then
    echo 'Initializing sites directory...'
    cp -aR /var/www/html/sites/. /mnt/drupal-sites/
    chown -R www-data:www-data /mnt/drupal-sites
    echo 'Initialization complete.'
  else
    echo 'Sites directory already initialized.'
  fi
  EOT
]