Skip to content

Commit 2cc13cb

Browse files
committed
docs: add Azure Container Apps service documentation
1 parent 33a0776 commit 2cc13cb

1 file changed

Lines changed: 355 additions & 0 deletions

File tree

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
---
2+
title: "Container Apps"
3+
description: Get started with Azure Container Apps on LocalStack
4+
template: doc
5+
---
6+
7+
import AzureFeatureCoverage from "../../../../components/feature-coverage/AzureFeatureCoverage";
8+
9+
## Introduction
10+
11+
Azure Container Apps is a serverless container platform for running containerized applications and microservices without managing Kubernetes infrastructure.
12+
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.
13+
For more information, see [Azure Container Apps overview](https://learn.microsoft.com/en-us/azure/container-apps/overview).
14+
15+
LocalStack for Azure provides a local environment for building and testing applications that use Azure Container Apps.
16+
The supported APIs are available on our [API Coverage section](#api-coverage), which provides information on the extent of Container Apps' integration with LocalStack.
17+
18+
## Getting started
19+
20+
This guide is designed for users new to Container Apps and assumes basic knowledge of the Azure CLI and our `lstk az` proxy.
21+
22+
Launch LocalStack using your preferred method. For more information, see [Introduction to LocalStack for Azure](/azure/getting-started/). Once the container is running, enable Azure CLI interception by running:
23+
24+
```bash
25+
lstk az start-interception
26+
```
27+
28+
This command points the `az` CLI away from the public Azure management REST API and toward the LocalStack for Azure emulator API.
29+
To revert this configuration, run:
30+
31+
```bash
32+
lstk az stop-interception
33+
```
34+
35+
This reconfigures the `az` CLI to send commands to the official Azure management REST API.
36+
37+
### Create a resource group
38+
39+
Create a resource group that will contain your Container Apps resources:
40+
41+
```bash
42+
az group create \
43+
--name rg-aca-demo \
44+
--location westeurope
45+
```
46+
47+
```bash title="Output"
48+
{
49+
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-aca-demo",
50+
"location": "westeurope",
51+
"managedBy": null,
52+
"name": "rg-aca-demo",
53+
"properties": {
54+
"provisioningState": "Succeeded"
55+
},
56+
"tags": null,
57+
"type": "Microsoft.Resources/resourceGroups"
58+
}
59+
```
60+
61+
### Create a Container Apps environment
62+
63+
Create a managed environment that will host your container apps and jobs:
64+
65+
```bash
66+
az containerapp env create \
67+
--name my-environment \
68+
--resource-group rg-aca-demo \
69+
--location westeurope \
70+
--logs-destination none
71+
```
72+
73+
```bash title="Output"
74+
{
75+
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-aca-demo/providers/Microsoft.App/managedEnvironments/my-environment",
76+
"location": "westeurope",
77+
"name": "my-environment",
78+
"properties": {
79+
"appLogsConfiguration": {
80+
"destination": null
81+
},
82+
"defaultDomain": "nicesmoke-4f9d21-westeurope.aca.azure.localhost.localstack.cloud",
83+
"provisioningState": "Succeeded"
84+
},
85+
"type": "Microsoft.App/managedEnvironments"
86+
...
87+
}
88+
```
89+
90+
Each environment receives a `defaultDomain` under `aca.azure.localhost.localstack.cloud`.
91+
This domain resolves to `127.0.0.1`, so the ingress endpoints of apps in the environment are directly reachable from your machine.
92+
93+
### Create a container app
94+
95+
Create a container app with external HTTP ingress:
96+
97+
```bash
98+
az containerapp create \
99+
--name quickstart \
100+
--resource-group rg-aca-demo \
101+
--environment my-environment \
102+
--image mcr.microsoft.com/k8se/quickstart:latest \
103+
--ingress external \
104+
--target-port 80 \
105+
--cpu 0.5 --memory 1Gi \
106+
--min-replicas 1 --max-replicas 3 \
107+
--revision-suffix v1
108+
```
109+
110+
```bash title="Output"
111+
{
112+
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-aca-demo/providers/Microsoft.App/containerapps/quickstart",
113+
"location": "westeurope",
114+
"name": "quickstart",
115+
"properties": {
116+
"configuration": {
117+
"activeRevisionsMode": "Single",
118+
"ingress": {
119+
"allowInsecure": false,
120+
"external": true,
121+
"fqdn": "quickstart--nicesmoke-4f9d21-westeurope.aca.azure.localhost.localstack.cloud",
122+
"targetPort": 80,
123+
"transport": "Auto"
124+
}
125+
},
126+
"latestReadyRevisionName": "quickstart--v1",
127+
"latestRevisionName": "quickstart--v1",
128+
"provisioningState": "Succeeded",
129+
"runningStatus": "Running",
130+
"template": {
131+
"containers": [
132+
{
133+
"image": "mcr.microsoft.com/k8se/quickstart:latest",
134+
"name": "quickstart",
135+
"resources": {
136+
"cpu": 0.5,
137+
"memory": "1Gi"
138+
}
139+
}
140+
],
141+
"revisionSuffix": "v1",
142+
"scale": {
143+
"maxReplicas": 3,
144+
"minReplicas": 1
145+
}
146+
}
147+
},
148+
"type": "Microsoft.App/containerApps"
149+
...
150+
}
151+
```
152+
153+
:::note
154+
The first container app or job in an environment provisions a local Kubernetes (k3d) cluster backing that environment, so the first create can take a few minutes.
155+
Subsequent deployments into the same environment are much faster.
156+
:::
157+
158+
### Invoke the container app
159+
160+
Retrieve the ingress FQDN and send a request to the running app.
161+
The FQDN is served by the LocalStack gateway on port `4566` with a valid TLS certificate:
162+
163+
```bash
164+
FQDN=$(az containerapp show \
165+
--name quickstart \
166+
--resource-group rg-aca-demo \
167+
--query "properties.configuration.ingress.fqdn" \
168+
--output tsv)
169+
170+
curl -s -o /dev/null -w "%{http_code}\n" "https://$FQDN:4566/"
171+
```
172+
173+
```bash title="Output"
174+
200
175+
```
176+
177+
You can also open `https://$FQDN:4566/` in your browser to see the welcome page of the quickstart image.
178+
179+
### Manage secrets
180+
181+
Add a secret to the container app:
182+
183+
```bash
184+
az containerapp secret set \
185+
--name quickstart \
186+
--resource-group rg-aca-demo \
187+
--secrets api-key=top-secret
188+
```
189+
190+
List the secrets, including their values:
191+
192+
```bash
193+
az containerapp secret list \
194+
--name quickstart \
195+
--resource-group rg-aca-demo \
196+
--show-values
197+
```
198+
199+
```bash title="Output"
200+
[
201+
{
202+
"identity": null,
203+
"keyVaultUrl": null,
204+
"name": "api-key",
205+
"value": "top-secret"
206+
}
207+
]
208+
```
209+
210+
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.
211+
212+
### Update the app and work with revisions
213+
214+
Update the container app with a new environment variable.
215+
Every change to the app template mints a new revision:
216+
217+
```bash
218+
az containerapp update \
219+
--name quickstart \
220+
--resource-group rg-aca-demo \
221+
--revision-suffix v2 \
222+
--set-env-vars GREETING=hello
223+
```
224+
225+
List the revisions of the app:
226+
227+
```bash
228+
az containerapp revision list \
229+
--name quickstart \
230+
--resource-group rg-aca-demo \
231+
--query "[].name" \
232+
--output tsv
233+
```
234+
235+
```bash title="Output"
236+
quickstart--v1
237+
quickstart--v2
238+
```
239+
240+
In the default `Single` revisions mode, the latest ready revision serves all traffic and older revisions are deactivated automatically.
241+
In `Multiple` mode, revisions stay active and can be deactivated and re-activated with `az containerapp revision deactivate` and `az containerapp revision activate`.
242+
243+
### Run a job
244+
245+
Create a manually triggered job in the same environment:
246+
247+
```bash
248+
az containerapp job create \
249+
--name my-job \
250+
--resource-group rg-aca-demo \
251+
--environment my-environment \
252+
--trigger-type Manual \
253+
--replica-timeout 1800 \
254+
--image mcr.microsoft.com/k8se/quickstart-jobs:latest \
255+
--cpu 0.25 --memory 0.5Gi
256+
```
257+
258+
Start an execution of the job.
259+
The execution runs as a real container and the command returns once it reaches a terminal state:
260+
261+
```bash
262+
az containerapp job start \
263+
--name my-job \
264+
--resource-group rg-aca-demo
265+
```
266+
267+
```bash title="Output"
268+
{
269+
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-aca-demo/providers/Microsoft.App/jobs/my-job/executions/my-job-8b31fc2",
270+
"name": "my-job-8b31fc2"
271+
}
272+
```
273+
274+
List the executions of the job to inspect their status:
275+
276+
```bash
277+
az containerapp job execution list \
278+
--name my-job \
279+
--resource-group rg-aca-demo \
280+
--query "[].{name:name, status:properties.status}"
281+
```
282+
283+
```bash title="Output"
284+
[
285+
{
286+
"name": "my-job-8b31fc2",
287+
"status": "Succeeded"
288+
}
289+
]
290+
```
291+
292+
### Delete and verify
293+
294+
Delete the container app and the job, then delete the environment:
295+
296+
```bash
297+
az containerapp delete \
298+
--name quickstart \
299+
--resource-group rg-aca-demo \
300+
--yes
301+
302+
az containerapp job delete \
303+
--name my-job \
304+
--resource-group rg-aca-demo \
305+
--yes
306+
307+
az containerapp env delete \
308+
--name my-environment \
309+
--resource-group rg-aca-demo \
310+
--yes
311+
```
312+
313+
Deleting a container app removes its containers from the local cluster.
314+
An environment can only be deleted once all apps, jobs, and managed certificates in it have been removed.
315+
316+
Verify the resource group is now empty:
317+
318+
```bash
319+
az containerapp list \
320+
--resource-group rg-aca-demo
321+
```
322+
323+
```bash title="Output"
324+
[]
325+
```
326+
327+
## Features
328+
329+
- **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.
330+
- **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.
331+
- **Revisions:** Both `Single` and `Multiple` revision modes are supported, including revision minting on template changes, activation and deactivation, and per-revision FQDNs.
332+
- **Secrets:** Inline secrets and Key Vault references are resolved and injected into containers as environment variables or secret volume mounts.
333+
- **Private registries:** Registry credentials with a password secret reference are used to pull images, including images hosted in the emulated Azure Container Registry.
334+
- **Health probes:** Liveness, readiness, and startup probes (HTTP and TCP) are enforced by the local cluster.
335+
- **Container logs:** `az containerapp logs show` streams logs directly from the running container via each replica's log stream endpoint.
336+
- **Jobs:** Manually started job executions run to completion and report `Succeeded` or `Failed`; parallelism and replica completion count are honored.
337+
- **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.
338+
339+
## Limitations
340+
341+
- **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`).
342+
- **No traffic splitting:** Traffic weights across revisions are stored but not enforced at the data plane; the latest ready revision serves all requests.
343+
- **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.
344+
- **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.
345+
- **No Dapr sidecar:** Dapr components and app-level Dapr configuration are stored and validated, but no Dapr sidecar is injected into running containers.
346+
- **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.
347+
- **No interactive log streaming or exec:** `az containerapp logs show --follow`, system logs (`--type system`), and `az containerapp exec` are not supported.
348+
349+
## Samples
350+
351+
- [Guestbook on Azure Container Apps with Blob Storage and Container Registry](https://github.com/localstack/localstack-azure-samples/tree/main/samples/container-apps-blob-storage/python/)
352+
353+
## API Coverage
354+
355+
<AzureFeatureCoverage service="Microsoft.App" client:load />

0 commit comments

Comments
 (0)