Skip to content
Get Started for Free

Container Apps

Azure Container Apps is a serverless container platform for running containerized applications and microservices without managing Kubernetes infrastructure. Applications are deployed into a managed environment, receive an HTTPS ingress endpoint, and are versioned through revisions, while background and scheduled work runs as jobs. For more information, see Azure Container Apps overview.

LocalStack for Azure provides a local environment for building and testing applications that use Azure Container Apps. The supported APIs are available on our API Coverage section, which provides information on the extent of Container Apps’ integration with LocalStack.

This guide is designed for users new to Container Apps and assumes basic knowledge of the Azure CLI and our lstk az proxy.

Launch LocalStack using your preferred method. For more information, see Introduction to LocalStack for Azure. Once the container is running, enable Azure CLI interception by running:

Terminal window
lstk az start-interception

This command points the az CLI away from the public Azure management REST API and toward the LocalStack for Azure emulator API. To revert this configuration, run:

Terminal window
lstk az stop-interception

This reconfigures the az CLI to send commands to the official Azure management REST API.

Create a resource group that will contain your Container Apps resources:

Terminal window
az group create \
--name rg-aca-demo \
--location westeurope
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-aca-demo",
"location": "westeurope",
"managedBy": null,
"name": "rg-aca-demo",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}

Create a managed environment that will host your container apps and jobs:

Terminal window
az containerapp env create \
--name my-environment \
--resource-group rg-aca-demo \
--location westeurope \
--logs-destination none
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-aca-demo/providers/Microsoft.App/managedEnvironments/my-environment",
"location": "westeurope",
"name": "my-environment",
"properties": {
"appLogsConfiguration": {
"destination": null
},
"defaultDomain": "nicesmoke-4f9d21-westeurope.aca.azure.localhost.localstack.cloud",
"provisioningState": "Succeeded"
},
"type": "Microsoft.App/managedEnvironments"
...
}

Each environment receives a defaultDomain under aca.azure.localhost.localstack.cloud. This domain resolves to 127.0.0.1, so the ingress endpoints of apps in the environment are directly reachable from your machine.

Create a container app with external HTTP ingress:

Terminal window
az containerapp create \
--name quickstart \
--resource-group rg-aca-demo \
--environment my-environment \
--image mcr.microsoft.com/k8se/quickstart:latest \
--ingress external \
--target-port 80 \
--cpu 0.5 --memory 1Gi \
--min-replicas 1 --max-replicas 3 \
--revision-suffix v1
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-aca-demo/providers/Microsoft.App/containerapps/quickstart",
"location": "westeurope",
"name": "quickstart",
"properties": {
"configuration": {
"activeRevisionsMode": "Single",
"ingress": {
"allowInsecure": false,
"external": true,
"fqdn": "quickstart--nicesmoke-4f9d21-westeurope.aca.azure.localhost.localstack.cloud",
"targetPort": 80,
"transport": "Auto"
}
},
"latestReadyRevisionName": "quickstart--v1",
"latestRevisionName": "quickstart--v1",
"provisioningState": "Succeeded",
"runningStatus": "Running",
"template": {
"containers": [
{
"image": "mcr.microsoft.com/k8se/quickstart:latest",
"name": "quickstart",
"resources": {
"cpu": 0.5,
"memory": "1Gi"
}
}
],
"revisionSuffix": "v1",
"scale": {
"maxReplicas": 3,
"minReplicas": 1
}
}
},
"type": "Microsoft.App/containerApps"
...
}

Retrieve the ingress FQDN and send a request to the running app. The FQDN is served by the LocalStack gateway on port 4566 with a valid TLS certificate:

Terminal window
FQDN=$(az containerapp show \
--name quickstart \
--resource-group rg-aca-demo \
--query "properties.configuration.ingress.fqdn" \
--output tsv)
curl -s -o /dev/null -w "%{http_code}\n" "https://$FQDN:4566/"
Output
200

You can also open https://$FQDN:4566/ in your browser to see the welcome page of the quickstart image.

Add a secret to the container app:

Terminal window
az containerapp secret set \
--name quickstart \
--resource-group rg-aca-demo \
--secrets api-key=top-secret

List the secrets, including their values:

Terminal window
az containerapp secret list \
--name quickstart \
--resource-group rg-aca-demo \
--show-values
Output
[
{
"identity": null,
"keyVaultUrl": null,
"name": "api-key",
"value": "top-secret"
}
]

Secrets can be referenced from environment variables via secretref:, mounted as secret volumes, and defined as Key Vault references that are resolved from the emulated Key Vault.

Update the container app with a new environment variable. Every change to the app template mints a new revision:

Terminal window
az containerapp update \
--name quickstart \
--resource-group rg-aca-demo \
--revision-suffix v2 \
--set-env-vars GREETING=hello

List the revisions of the app:

Terminal window
az containerapp revision list \
--name quickstart \
--resource-group rg-aca-demo \
--query "[].name" \
--output tsv
Output
quickstart--v1
quickstart--v2

In the default Single revisions mode, the latest ready revision serves all traffic and older revisions are deactivated automatically. In Multiple mode, revisions stay active and can be deactivated and re-activated with az containerapp revision deactivate and az containerapp revision activate.

Create a manually triggered job in the same environment:

Terminal window
az containerapp job create \
--name my-job \
--resource-group rg-aca-demo \
--environment my-environment \
--trigger-type Manual \
--replica-timeout 1800 \
--image mcr.microsoft.com/k8se/quickstart-jobs:latest \
--cpu 0.25 --memory 0.5Gi

Start an execution of the job. The execution runs as a real container and the command returns once it reaches a terminal state:

Terminal window
az containerapp job start \
--name my-job \
--resource-group rg-aca-demo
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-aca-demo/providers/Microsoft.App/jobs/my-job/executions/my-job-8b31fc2",
"name": "my-job-8b31fc2"
}

List the executions of the job to inspect their status:

Terminal window
az containerapp job execution list \
--name my-job \
--resource-group rg-aca-demo \
--query "[].{name:name, status:properties.status}"
Output
[
{
"name": "my-job-8b31fc2",
"status": "Succeeded"
}
]

Delete the container app and the job, then delete the environment:

Terminal window
az containerapp delete \
--name quickstart \
--resource-group rg-aca-demo \
--yes
az containerapp job delete \
--name my-job \
--resource-group rg-aca-demo \
--yes
az containerapp env delete \
--name my-environment \
--resource-group rg-aca-demo \
--yes

Deleting a container app removes its containers from the local cluster. An environment can only be deleted once all apps, jobs, and managed certificates in it have been removed.

Verify the resource group is now empty:

Terminal window
az containerapp list \
--resource-group rg-aca-demo
Output
[]
  • Real container execution: Container apps and job executions run as real containers on a local Kubernetes (k3d) cluster that LocalStack provisions per managed environment. Set LS_AZURE_CONTAINER_APPS_RUNTIME=0 to manage Container Apps resources in control-plane-only mode without starting containers.
  • Live HTTPS ingress: Every app with ingress gets an FQDN that resolves to 127.0.0.1 and is served with a valid TLS certificate. CORS policies, IP security restrictions, HTTPS redirects, and session affinity are enforced at the ingress.
  • Revisions: Both Single and Multiple revision modes are supported, including revision minting on template changes, activation and deactivation, and per-revision FQDNs.
  • Secrets: Inline secrets and Key Vault references are resolved and injected into containers as environment variables or secret volume mounts.
  • Private registries: Registry credentials with a password secret reference are used to pull images, including images hosted in the emulated Azure Container Registry.
  • Health probes: Liveness, readiness, and startup probes (HTTP and TCP) are enforced by the local cluster.
  • Container logs: az containerapp logs show streams logs directly from the running container via each replica’s log stream endpoint.
  • Jobs: Manually started job executions run to completion and report Succeeded or Failed; parallelism and replica completion count are honored.
  • Auxiliary resources: Dapr components, environment storages, managed certificates, and HTTP route configs support full CRUD with validation. HTTP route configs perform real path-based routing, including exact and prefix matches and prefix rewrites.
  • No autoscaling: KEDA scale rules are stored and echoed back but not evaluated, and scale-to-zero is not supported. Apps run with a fixed replica count derived from minReplicas (at least 1, capped by maxReplicas).
  • No traffic splitting: Traffic weights across revisions are stored but not enforced at the data plane; the latest ready revision serves all requests.
  • No automatic job triggers: Scheduled (cron) and event-driven job triggers are stored but never fire; az containerapp job start is the only way to create an execution.
  • Azure Files storages are metadata-only: Environment storages can be managed via CRUD, but AzureFile and NfsAzureFile volumes are skipped at deploy time and the container starts without the mount.
  • No Dapr sidecar: Dapr components and app-level Dapr configuration are stored and validated, but no Dapr sidecar is injected into running containers.
  • No real certificates or domain validation: Managed certificates skip certificate issuance and DNS validation, custom domains are stored without verification, and custom hostname analysis always reports the domain verification as failed.
  • No interactive log streaming or exec: az containerapp logs show --follow, system logs (--type system), and az containerapp exec are not supported.
OperationImplemented
Page 1 of 0
Was this page helpful?