Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

3.1.3. Deploying Containers to App Service

💡 First Principle: App Service treats your container as a black box with two contracts: it must listen on a declared port, and it reads configuration from environment variables the platform injects at startup. Honor both contracts and the image from 3.1.1 runs unmodified across dev, staging, and production — configuration varies, the artifact never does.

App Service (Web App for Containers) is the lowest-friction hosting from the 1.2.1 spectrum: bring an image, get TLS, scaling, and deployment slots. Creation points the app at an ACR image, with managed-identity pull (AcrPull) as best practice — no registry passwords in app config.

The configuration contract is where exam questions live. App settings become environment variables inside the container at runtime, and they override any same-named ENV from the Dockerfile:

az webapp config appsettings set --name rag-api --resource-group rg \
  --settings MODEL_ENDPOINT="https://..." COSMOS_DB="chatdb" \
  WEBSITES_PORT=8000 \
  OPENAI_KEY="@Microsoft.KeyVault(SecretUri=https://kv.vault.azure.net/secrets/openai-key/)"

Three details deserve flagging. First, WEBSITES_PORT tells App Service which port your container listens on — the setting behind most "container deploys but never responds" mysteries (App Service assumes 80; your FastAPI app listens on 8000). Second, the @Microsoft.KeyVault(...) syntax is a Key Vault reference: the app setting holds a pointer, App Service's managed identity fetches the secret at startup, and code just reads an ordinary environment variable — secrets absent from both image and configuration, previewing 5.1.1. Third, changing app settings restarts the container — configuration is applied at startup, not live-patched.

This mechanism is precisely why the parent misconception is wrong: one image, promoted untouched through environments, each environment supplying its own variables — the container equivalent of the "build once, deploy many" doctrine.

⚠️ Exam Trap: A custom container that starts, logs nothing wrong, but times out on every request is missing WEBSITES_PORT. Distractors will offer scaling up, enabling continuous deployment, or changing the image — the port declaration is the fix.

Slots deserve a mention here too: deployment slots let a new container version warm up on a staging slot and swap into production atomically, with app settings optionally staying slot-sticky.

Reflection Question: Why does resolving secrets via Key Vault references beat passing them as plain app settings, given both end up as environment variables in the container?

Alvin Varughese
Written byAlvin Varughese
Founder18 professional certifications