Skip to content

Custom Domains and Certificates

Azure Container Apps supports custom hostnames and TLS certificates so you can serve production traffic on your own domain instead of the default azurecontainerapps.io endpoint. Managed certificates are validated through DigiCert and require public DNS reachability during issuance.

Architecture

flowchart TD
    U[Client] --> DNS[Public DNS zone]
    DNS --> INGRESS[Container Apps ingress]
    DNS --> TXT[TXT record: asuid.<host>]
    TXT --> ACA[Container Apps domain verification]
    ACA --> DIGI[DigiCert domain validation]
    DIGI --> CERT[Managed certificate issued]
flowchart TD
    U[Client HTTPS request] --> CDNS[Custom domain DNS]
    CDNS --> INGRESS[Container Apps ingress]
    INGRESS --> APP[Container App revision]

Prerequisites

  • Existing Container App: $APP_NAME in $RG
  • Existing Container Apps environment: $ACA_ENV_NAME
  • A public DNS zone you control for your domain
  • Azure CLI with Container Apps extension
az extension add --name containerapp --upgrade
Command Why it is used
az extension add ... Installs or updates the Container Apps Azure CLI extension.

Configure Custom Domain

  1. Get environment static IP (used for apex A record) and app default FQDN (used for subdomain CNAME):
export ENV_STATIC_IP=$(az containerapp env show \
  --name "$ACA_ENV_NAME" \
  --resource-group "$RG" \
  --query "properties.staticIp" \
  --output tsv)

export APP_FQDN=$(az containerapp show \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --query "properties.configuration.ingress.fqdn" \
  --output tsv)
Command Purpose
export ENV_STATIC_IP=$(az containerapp env show --name "$ACA_ENV_NAME" --resource-group "$RG" --query "properties.staticIp" --output tsv) Captures the environment static IP used for the apex-domain A record when binding a Python app to a custom domain.
export APP_FQDN=$(az containerapp show --name "$APP_NAME" --resource-group "$RG" --query "properties.configuration.ingress.fqdn" --output tsv) Captures the app's current ingress hostname so you can create the correct CNAME or validate the existing endpoint before cutover.
  1. Get the domain verification value (asuid) from the app:
export CUSTOM_DOMAIN_VERIFICATION_ID=$(az containerapp show \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --query "properties.customDomainVerificationId" \
  --output tsv)
Command Purpose
export CUSTOM_DOMAIN_VERIFICATION_ID=$(az containerapp show --name "$APP_NAME" --resource-group "$RG" --query "properties.customDomainVerificationId" --output tsv) Extracts the verification token that must be published in DNS before Container Apps will allow the custom domain to be attached.
  1. Create DNS records (example with Azure DNS):
# Apex domain example: contoso.com -> environment static IP
az network dns record-set a add-record \
  --resource-group "$DNS_RG" \
  --zone-name "contoso.com" \
  --record-set-name "@" \
  --ipv4-address "$ENV_STATIC_IP"

# Subdomain example: www.contoso.com -> app FQDN
az network dns record-set cname set-record \
  --resource-group "$DNS_RG" \
  --zone-name "contoso.com" \
  --record-set-name "www" \
  --cname "$APP_FQDN"

# TXT verification record required by Container Apps
az network dns record-set txt add-record \
  --resource-group "$DNS_RG" \
  --zone-name "contoso.com" \
  --record-set-name "asuid.www" \
  --value "$CUSTOM_DOMAIN_VERIFICATION_ID"
Command Why it is used
az network dns record-set ... Creates or inspects networking resources such as VNets, DNS zones, routes, or private endpoints.
  1. Add hostname to the Container App:
az containerapp hostname add \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --hostname "www.contoso.com"
Command Why it is used
az containerapp hostname add ... Manages custom hostname bindings for ingress.

Create Managed Certificate

Bind the hostname with a managed certificate. The certificate is automatically provisioned and validated using DNS.

az containerapp hostname bind \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --hostname "www.contoso.com" \
  --environment "$ACA_ENV_NAME" \
  --validation-method CNAME
Command Why it is used
az containerapp hostname bind ... Manages custom hostname bindings for ingress.

If you bring your own certificate instead of managed issuance, upload it to the environment with az containerapp env certificate upload and then bind it with az containerapp hostname bind --certificate <cert-name>.

Enforce HTTPS

Set ingress transport to HTTPS-only:

az containerapp ingress update \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --transport auto \
  --allow-insecure false
Command Why it is used
az containerapp ingress update ... Updates ingress settings on an existing Container App.

Verification

az containerapp hostname list \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --output table

az containerapp env certificate list \
  --name "$ACA_ENV_NAME" \
  --resource-group "$RG" \
  --output table
Command Why it is used
az containerapp hostname list ... Manages custom hostname bindings for ingress.

Then verify HTTPS from a client:

curl --verbose https://www.contoso.com/

Troubleshooting

  • Managed certificate remains pending/failed: confirm the app hostname is publicly reachable and DNS records have propagated.
  • DigiCert validation fails: verify asuid.<host> TXT record value exactly matches the app verification ID.
  • CAA record blocks issuance: ensure your CAA policy allows DigiCert certificate issuance for your domain.
  • HTTPS still not active: confirm hostname is bound to the expected certificate and certificate status is Ready.

Advanced Topics

  • Use apex + subdomain patterns together (A record for apex, CNAME for subdomain).
  • Standardize DNS TTL strategy to reduce cutover delays during migration.
  • Pair custom domains with WAF/CDN when you need global edge security and acceleration.

See Also

Sources