Azure Container Apps (ACA)

Azure Container Apps (ACA) runs RegScale as a fully managed container on Microsoft Azure — without operating a Kubernetes cluster. ACA handles ingress, TLS termination, and autoscaling, while RegScale connects to an external Azure SQL database and stores uploaded files directly in an Azure Blob Storage container via a managed identity.

📘

Before you begin

Complete the Prerequisites (database, networking) and review the Sizing Guide. After deployment, follow the Post-Deployment Steps.

Architecture

  • RegScale Core Platform — the regscale/regscale container image running in an Azure Container Apps environment, listening on HTTP port 80.
  • Ingress & TLS — ACA's built-in ingress exposes RegScale over HTTPS and terminates TLS, so no container-level certificate is required.
  • SQL Server — an external Azure SQL Database or Azure SQL Managed Instance (SQL Server 2022+; see Prerequisites › Database Configuration). RegScale connects via a connection string.
  • File Storage — an Azure Blob Storage container. RegScale writes to it natively using a user-assigned managed identity (no storage keys, no filesystem mount).
  • Secrets — JWT, encryption, and database credentials are stored as Container Apps secrets and injected as environment variables.

Prerequisites

  1. An Azure subscription and the Azure CLI (az) with the Container Apps extension:
    az extension add --name containerapp --upgrade
    az provider register --namespace Microsoft.App
    az provider register --namespace Microsoft.OperationalInsights
    
  2. Access to a container registry for the RegScale image — Docker Hub (regscale/regscale:x.x.x.x) or Iron Bank (registry1.dso.mil/ironbank/regscale/regscale:x.x.x.x).
  3. An external Azure SQL Database (or Managed Instance), SQL Server 2022+ with Full-Text Search enabled.
  4. A resource group and region to deploy into.

📘

Replace x.x.x.x with the RegScale release you want to deploy. The latest release tags can be found in the RegScale Changelog.

Step 1 — Create the Container Apps Environment

az group create --name regscale-rg --location eastus

az containerapp env create \
  --name regscale-env \
  --resource-group regscale-rg \
  --location eastus

Step 2 — Create Blob Storage

Create a storage account and a blob container for RegScale's files:

az storage account create \
  --name regscalestorage \
  --resource-group regscale-rg \
  --location eastus \
  --sku Standard_LRS \
  --kind StorageV2

az storage container create \
  --name regscale-files \
  --account-name regscalestorage \
  --auth-mode login

Step 3 — Create a Managed Identity for Blob Access

Create a user-assigned managed identity and grant it access to the blob container. RegScale uses this identity to read and write files — no storage keys are stored in the app.

# Create the identity
az identity create --name regscale-identity --resource-group regscale-rg

IDENTITY_ID=$(az identity show -n regscale-identity -g regscale-rg --query id -o tsv)
IDENTITY_CLIENT_ID=$(az identity show -n regscale-identity -g regscale-rg --query clientId -o tsv)
IDENTITY_PRINCIPAL_ID=$(az identity show -n regscale-identity -g regscale-rg --query principalId -o tsv)

# Grant the identity access to blob data on the storage account
STORAGE_ID=$(az storage account show -n regscalestorage -g regscale-rg --query id -o tsv)
az role assignment create \
  --assignee "$IDENTITY_PRINCIPAL_ID" \
  --role "Storage Blob Data Contributor" \
  --scope "$STORAGE_ID"

Step 4 — Create the Container App

Generate strong, unique keys first (32-char hex, 32 UTF-8 bytes each):

echo "JWTSecretKey=$(openssl rand -hex 16)"
echo "EncryptionKey=$(openssl rand -hex 16)"

⚠️

Do not use openssl rand -base64 32 for these keys — it produces 44 characters (not 32 bytes) and will fail the legacy AES key-length check.

Create the container app, attaching the managed identity, secrets, and environment variables:

az containerapp create \
  --name regscale \
  --resource-group regscale-rg \
  --environment regscale-env \
  --image regscale/regscale:x.x.x.x \
  --user-assigned "$IDENTITY_ID" \
  --ingress external \
  --target-port 80 \
  --transport auto \
  --cpu 2.0 --memory 4.0Gi \
  --min-replicas 1 --max-replicas 3 \
  --secrets \
      jwt-secret-key=<yourJWTSecretKey> \
      encryption-key=<yourEncryptionKey> \
      sql-conn="Server=tcp:<db-server>.database.windows.net,1433;Initial Catalog=REGSCALE;Persist Security Info=False;User ID=<db_admin>;Password=<db_password>;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" \
  --env-vars \
      ASPNETCORE_HTTP_PORTS=80 \
      ASPNETCORE_URLS=http://+:80 \
      StoredFilesPath=atlas-files \
      FileSizeLimit=104857600 \
      AZURE_STORAGE_ACCOUNT=regscalestorage \
      AZURE_BLOB_CONTAINER=regscale-files \
      AZURE_CLIENT_ID="$IDENTITY_CLIENT_ID" \
      JWTSecretKey=secretref:jwt-secret-key \
      EncryptionKey=secretref:encryption-key \
      SQLConn=secretref:sql-conn

Notes:

  • AZURE_CLIENT_ID tells RegScale which user-assigned managed identity to use for Blob access.
  • --target-port 80 matches the container's HTTP port; ACA's ingress provides the public HTTPS endpoint.
  • Set --cpu/--memory to match your Sizing Guide tier (the example uses 2 vCPU / 4 GB — the minimum web tier).

Step 5 — Pull from a Private Registry (Iron Bank)

If you pull from Iron Bank or another private registry, add a registry credential:

az containerapp registry set \
  --name regscale \
  --resource-group regscale-rg \
  --server registry1.dso.mil \
  --username <registry-username> \
  --password <registry-password>

For Docker Hub public images, no registry credentials are required.

Step 6 — Access RegScale

Get the application URL:

az containerapp show \
  --name regscale \
  --resource-group regscale-rg \
  --query properties.configuration.ingress.fqdn -o tsv

Browse to https://<fqdn> and complete the Post-Deployment Steps.

Custom Domain and TLS

ACA terminates TLS at its ingress, so you do not configure certificates inside the container. To use your own domain, add a custom domain and certificate to the container app:

az containerapp hostname add \
  --hostname regscale.yourdomain.com \
  --name regscale \
  --resource-group regscale-rg

You can bind a managed certificate or upload your own. See the Azure Container Apps custom domain documentation for details.

Scaling

  • Adjust --min-replicas/--max-replicas to control scale. Because files are stored in shared Azure Blob Storage (not local disk), multiple replicas can run concurrently.
  • Update the image tag and redeploy to upgrade — see the Upgrade Guide.