AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Deploying Azure Container Apps

skill-alexpizarro-azure-lean-stack-skills-deploying-azure-container-apps · by alexpizarro

Deploys Docker containers to Azure Container Apps with scale-to-zero, multi-container sidecars, shared managed environments, and Container Apps Jobs for batch workloads. Use when SWA + FC1 don't fit — long-running servers, WebSocket/SSE streaming, custom Docker runtimes, scheduled or queue-driven background jobs, or multi-process workloads with sidecars.

No reviews yet
0 installs
42 views
0.0% view→install

Install

$ agentstack add skill-alexpizarro-azure-lean-stack-skills-deploying-azure-container-apps

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-alexpizarro-azure-lean-stack-skills-deploying-azure-container-apps)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
4mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Deploying Azure Container Apps? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Deploying Azure Container Apps

Scale-to-zero Docker containers for workloads SWA + FC1 can't handle: long-running servers, WebSocket/SSE, streaming, custom runtimes, multi-process sidecars, and run-to-completion background jobs.

When to use Container Apps

| Need | Use | |------|-----| | CRUD API + React frontend | SWA — not this | | Timer/queue trigger, AI workload, 30s requests | Container App (this skill) | | WebSocket / SSE / streaming | Container App with --request-timeout 1800 | | Sidecar (e.g. headless browser, embedded DB) | Container App multi-container | | Batch / cron / one-shot processor | Container Apps Job (this skill, jobs section) | | Multiple related apps sharing logs/networking | Shared managed environment (this skill) |

Cost defaults

| State | Cost | |-------|------| | Idle (minReplicas: 0) | $0 | | Active (0.25 vCPU, 0.5 GiB) | pennies/month at low traffic | | Always warm (minReplicas: 1) | ~$5/month (no cold start) | | Log Analytics workspace | bound by dailyQuotaGb on the workspace (see [instrumenting-azure-app-insights](../instrumenting-azure-app-insights/SKILL.md)) |

Critical pattern: share the managed environment

A Microsoft.App/managedEnvironments resource is the unit that owns networking + Log Analytics. One environment can host many Container Apps and Jobs. Sharing saves Log Analytics workspace cost and simplifies VNet wiring.

// One env created once
module env 'modules/managedEnv.bicep' = { ... }

// Multiple apps reuse it
module appA 'modules/containerApp.bicep' = {
  params: { managedEnvironmentId: env.outputs.id, ... }
}
module appB 'modules/containerApp.bicep' = {
  params: { managedEnvironmentId: env.outputs.id, ... }
}
module syncJob 'modules/containerAppJob.bicep' = {
  params: { environmentId: env.outputs.id, ... }
}

See [references/multi-app-shared-env.md](references/multi-app-shared-env.md).

Container Apps Jobs — scale-to-zero by nature

For run-to-completion workloads (batch processing, sync, scheduled crawls), use Microsoft.App/jobs instead of a Container App. A Job only runs when triggered; there are no idle replicas.

Triggers:

  • Manual — started via az containerapp job start (with optional --env-vars for per-run inputs)
  • Schedule — cron expression
  • Event — Azure queue/event source
resource job 'Microsoft.App/jobs@2024-03-01' = {
  properties: {
    environmentId: env.id
    workloadProfileName: 'Consumption'   // no idle billing
    configuration: {
      triggerType: 'Manual'
      replicaTimeout: 600                // seconds — max single-run duration
      replicaRetryLimit: 0
      manualTriggerConfig: {
        parallelism: 1
        replicaCompletionCount: 1
      }
    }
    template: { ... }
  }
}

Trigger with per-run inputs:

az containerapp job start \
  --name "$JOB_NAME" \
  --resource-group "$RG" \
  --env-vars "INPUT_ID=$ID" "BLOB_PATH=$PATH"

See [references/aca-jobs.md](references/aca-jobs.md).

Multi-container sidecar pattern

A Container App can run multiple containers in a single replica, sharing localhost networking. Useful for embedded dependencies like a headless browser:

template:
  containers:
    - name: app
      image: $ACR/app:$TAG
      env:
        - name: BROWSER_URL
          value: http://localhost:11235   # talks to sidecar
    - name: browser
      image: docker.io/unclecode/crawl4ai:0.8.6   # pin — avoid :latest drift

Apply via YAML to keep both containers atomic:

az containerapp update --name "$APP_NAME" --resource-group "$RG" --yaml app.yaml

See [references/sidecar-pattern.md](references/sidecar-pattern.md).

Secrets via secretref:

Container App secrets are write-only — values can't be read back. Link to env vars:

az containerapp secret set --name "$APP_NAME" --resource-group "$RG" \
  --secrets "openai-key=$OPENAI_API_KEY"

az containerapp update --name "$APP_NAME" --resource-group "$RG" \
  --set-env-vars "OPENAI_API_KEY=secretref:openai-key"

Gotcha: updating a secret value doesn't restart replicas. Force a revision restart:

REVISION=$(az containerapp show --name "$APP_NAME" --resource-group "$RG" \
  --query "properties.latestRevisionName" -o tsv)
az containerapp revision restart --name "$APP_NAME" --resource-group "$RG" --revision "$REVISION"

Request timeout for SSE / WebSocket

Default is 240 seconds. Streaming connections drop at 4 minutes without this:

az containerapp ingress update --name "$APP_NAME" --resource-group "$RG" --request-timeout 1800

Maximum: 3600 (1 hour).

Probes (health checks)

Liveness + readiness probes prevent traffic to a starting container and recycle stuck ones:

probes:
  - type: liveness
    httpGet: { path: /health, port: 8000 }
    initialDelaySeconds: 10
    periodSeconds: 30
  - type: readiness
    httpGet: { path: /health, port: 8000 }
    initialDelaySeconds: 5
    periodSeconds: 10

See [references/probes.md](references/probes.md).

Image registry — GHCR vs ACR

| Registry | When | |----------|------| | GHCR (ghcr.io) | Public images, GitHub-hosted projects. Free for public repos. | | Docker Hub | Avoid anonymously (100 pulls/6h rate limit). Pin tags if used. | | ACR (Azure Container Registry) | Private images, fine-grained RBAC. ~$5/month Basic tier. |

For non-secret images, GHCR is the cheapest option. See [references/ghcr-vs-acr.md](references/ghcr-vs-acr.md).

Dockerfile template

FROM node:22-alpine

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build && npm prune --production

EXPOSE 8000
ENV NODE_ENV=production

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:8000/health || exit 1

CMD ["node", "dist/server.js"]

Key points:

  • Alpine for small images (faster cold start)
  • Build with devDeps, then npm prune --production
  • Use wget not curl (Alpine doesn't bundle curl)
  • Always expose /health

Composes with

  • [scaffolding-azure-bicep-infrastructure](../scaffolding-azure-bicep-infrastructure/SKILL.md) — for the modular toggle to add ACA
  • [optimizing-azure-blob-storage-cost](../optimizing-azure-blob-storage-cost/SKILL.md) — when the container uses blob storage
  • [instrumenting-azure-app-insights](../instrumenting-azure-app-insights/SKILL.md) — for the Log Analytics workspace + alerts
  • Microsoft azure-diagnostics for live container debugging via the Azure MCP

Templates

| File | Purpose | |------|---------| | [templates/containerApp.bicep](templates/containerApp.bicep) | HTTP Container App with scale-to-zero | | [templates/containerAppJob.bicep](templates/containerAppJob.bicep) | Manual-trigger Container Apps Job | | [templates/managedEnv.bicep](templates/managedEnv.bicep) | Shared managed environment (Consumption profile) | | [templates/multi-container.yaml](templates/multi-container.yaml) | YAML for sidecar pattern |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.