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/regscalecontainer 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
- 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 - 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). - An external Azure SQL Database (or Managed Instance), SQL Server 2022+ with Full-Text Search enabled.
- A resource group and region to deploy into.
Replace
x.x.x.xwith 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 32for 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_IDtells RegScale which user-assigned managed identity to use for Blob access.--target-port 80matches the container's HTTP port; ACA's ingress provides the public HTTPS endpoint.- Set
--cpu/--memoryto 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-replicasto 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.
