Azure Container Apps
A complete, plain-English guide to Azure Container Apps: what containers are, how the service runs them without making you manage servers, how it scales to zero and back, how traffic, security, networking and cost work, and how to design real systems with it.
Imagine you run a food truck business. In the old days, to serve customers in a new city you had to buy a truck, hire a mechanic, find parking, arrange fuel and keep the engine serviced. Now imagine a company that says: “Give us your recipe in a sealed lunch box. We will provide the truck, the driver, the fuel and the parking spot. When the queue grows we will bring more trucks, and when nobody is hungry we will send them all home and charge you nothing.” Azure Container Apps is that company. The sealed lunch box is a container, and the trucks are servers you never have to see.
This guide assumes you know nothing about the topic. Every new term is explained when it first appears, with an everyday comparison. By the end you will understand what containers are, how Azure Container Apps runs them, how scaling, traffic splitting, networking, security and pricing work, when to choose it over its alternatives, and how to avoid the mistakes that trip up beginners and experienced teams alike.
1The Problem Containers Solve
Before Azure Container Apps makes sense, we need to understand why the software world moved to containers.
“It works on my machine”
Every programmer has said it. An application runs perfectly on the developer’s laptop, then breaks on the test server and breaks differently in production. The reason is that software depends on many invisible things: the version of the operating system, the installed libraries, the settings, the language runtime and even the time zone. If any of these differ between machines, the application may behave differently or fail completely.
Imagine you bake a cake at home and it turns out perfectly. You give the recipe to a friend, but their oven runs hotter, their flour is different and their eggs are smaller. The cake fails. Now imagine instead that you ship them a sealed box containing the cake ingredients, the pan and a small portable oven, all pre-set. It will bake the same way anywhere. That sealed box is a container.
What a container is
A container is a lightweight, isolated package that bundles an application together with everything it needs to run: its code, its runtime, its libraries and its settings. Unlike a full virtual machine, a container does not carry an entire operating system inside it. Instead, many containers share the operating system kernel of the machine they run on, while the operating system keeps each container separated from the others. Because they skip the heavy duplication, containers start in seconds and use far less memory.
Image versus container
Two words are often confused. A container image is the frozen, read-only template: the recipe card plus ingredients, sealed in a box. A container is a running instance of that image: the cake actually baking. You can start many containers from one image, just as you can bake many cakes from one recipe. Images are stored in a registry, which is simply a library for images.
Container
A running, isolated package containing an application and its dependencies.
Image
The read-only template from which containers are started.
Registry
A storage service for images, such as Azure Container Registry or a public library.
Runtime
The software on a host machine that actually starts and supervises containers.
Orchestrator
A system that decides where containers run, restarts failed ones and scales them. Kubernetes is the best-known example.
Containers solve the consistency problem. The same image that passed testing is the exact thing that runs in production, so differences between environments shrink dramatically.
2From One Container to Thousands: Why Orchestration Exists
Running one container is easy. Running hundreds reliably is a full-time job unless something helps.
The management headache
As soon as an application is split into several services, each in its own container, new questions appear. Which machine should each container run on? What happens if a machine dies? How do containers find each other when addresses keep changing? How do you roll out a new version without downtime? How do you add more copies during a busy hour and remove them afterwards? Answering these by hand does not scale.
Kubernetes arrives
Kubernetes, created at Google and released as open source, became the standard answer. It treats a group of machines as one big pool, accepts descriptions of what you want to run, and constantly works to make reality match the description. If a container crashes, it starts another. If a machine dies, it moves the containers elsewhere. It is extremely powerful, but it is also complex, with many concepts to learn and many components to configure, secure and upgrade.
Kubernetes is like running your own airport. You get total control over runways, gates, baggage handling and air traffic, but you must hire and train staff for all of it. Many companies only want to fly somewhere; they do not want to operate an airport.
Where Azure Container Apps fits
Azure Container Apps is a managed platform that runs on top of Kubernetes technology but hides it from you. Microsoft operates the underlying cluster and its open source components, and you interact with higher-level concepts such as apps, revisions and scaling rules. You do not receive or manage the Kubernetes control plane directly. You get many of the benefits, namely automatic scaling, rolling updates, service discovery and health management, without the burden of operating the machinery.
Behind the scenes, the platform uses well-known open source projects: Kubernetes for orchestration, KEDA for event-driven scaling, Dapr for building blocks of distributed applications and Envoy as the proxy that handles incoming traffic. You benefit from them without installing any of them yourself.
Some people assume Container Apps is just a simplified Kubernetes with the same features. It is a deliberately opinionated platform. You gain simplicity but give up direct access to the Kubernetes API and some low-level controls. If you need custom operators or deep cluster tuning, a different service is the better fit.
3What Azure Container Apps Is, in Plain Words
A serverless platform for running containerised applications and jobs.
Serverless does not mean no servers
The word serverless confuses beginners. Servers certainly exist, but you do not provision, patch or think about them. You hand over the container, state how much processing power it needs, and the platform handles placement, scaling and maintenance. You are billed for resources your app actually consumes rather than for machines sitting idle waiting for work.
What you can run
Azure Container Apps supports containers built with any language or framework, as long as they are packaged as images and follow normal conventions. Typical workloads include public web applications, internal APIs, microservices, background workers that process queues, scheduled and one-off jobs, event-driven processors and machine learning inference services.
HTTP applications and APIs
Web front ends and REST or gRPC services that receive requests through built-in ingress and scale with traffic.
Microservices
Many small independent services that call each other privately and are deployed and scaled separately.
Event-driven workers
Containers that wake up when messages arrive in a queue or events appear on a stream, and sleep when the work is done.
Jobs
Containers that run to completion, either on a schedule, on demand or in response to events, then stop.
Headline features
Using Container Apps is like hiring a taxi company with an unlimited fleet rather than owning cars. You say where you want to go and how big your group is; you never think about oil changes, parking or what the cars do when nobody needs them.
4Core Building Blocks and Vocabulary
Six or seven concepts explain nearly everything in the service.
Environment
The secure boundary that groups container apps. Apps in the same environment share a virtual network and send their logs to the same place.
Container App
The main unit you deploy: one logical application or microservice, made of one or more containers.
Revision
An immutable snapshot of one version of a container app. Changing certain settings creates a new revision.
Replica
One running copy of a revision. Scaling means changing the number of replicas.
Job
A containerised task that runs to completion rather than serving requests forever.
Workload Profile
A choice of hardware flavour for the apps in an environment, such as shared pay-per-use capacity or dedicated machines.
Ingress
The configuration that lets traffic reach an app, either from the internet or only from inside the environment.
How they nest
An environment holds many container apps and jobs. Each container app has several revisions over its life. Each revision runs as one or more replicas. Each replica contains one or more containers that share storage and a network address, much as the several rooms of one flat share one front door.
flowchart TD
ENV[Container Apps Environment] --> APP1[Container App: Orders API]
ENV --> APP2[Container App: Web Front End]
ENV --> JOB[Job: Nightly Report]
APP1 --> REV1[Revision 1]
APP1 --> REV2[Revision 2]
REV2 --> REP1[Replica A]
REV2 --> REP2[Replica B]
REP1 --> C1[Main Container]
REP1 --> C2[Sidecar Container]
An environment is a shopping mall. Each container app is a shop in the mall. A revision is one edition of the shop’s layout. Replicas are the cashiers currently working behind the counter. The mall provides shared corridors, security and electricity for all the shops.
Put apps that must talk to each other privately, and that belong to the same system, in one environment. Separate unrelated systems, or different security zones, into different environments.
5Environments in Depth
The environment is the foundation on which everything else rests, so its design decisions matter early.
What an environment gives you
An environment is a secure boundary around a group of apps and jobs. Everything inside shares a virtual network, meaning a private network space, and sends its logs to a common destination. Apps in one environment can discover and call each other by name. Apps in different environments are isolated from each other by default, which is useful for separating teams, stages or customers.
Environment types and workload profiles
Environments come with different hardware models, selected through workload profiles. The consumption profile gives you shared, fully serverless capacity where you are billed for what your replicas use, and it can scale to zero. Dedicated profiles reserve specific machine sizes, including options with more memory or with graphics processors, for workloads that need predictable performance or special hardware. A single environment can mix profiles, so an ordinary web app can run on consumption capacity while a heavy analytics service sits on a dedicated profile.
| Profile | Capacity Model | Billing Idea | Best For |
|---|---|---|---|
| Consumption | Shared, fully managed, scales to zero | Pay for resources replicas actually use | Most web apps, APIs, workers, bursty or spiky workloads |
| Dedicated (general purpose) | Reserved machines of a chosen size | Pay for the machines while they exist, with apps packed onto them | Steady, high-volume apps needing predictable capacity |
| Dedicated (memory optimised) | Reserved machines with more memory per core | Pay for the machines | Large in-memory workloads |
| Dedicated (GPU) | Reserved machines with graphics processors | Pay for the machines | Model inference and graphics-heavy tasks |
Logging destination
Each environment sends system and application logs to a chosen destination. The usual choice is a Log Analytics workspace, a central store where logs can be searched and analysed. Other destinations are available, and you can also choose to route logs through Azure Monitor settings. Decide this early, because it affects how you will investigate problems.
Regions
An environment lives in one Azure region, such as Central India or West Europe. Apps inside it run in that region, and the platform can spread replicas across availability zones where the region supports them and zone redundancy is enabled. Choosing a region close to your users reduces delay, and legal requirements may restrict where data may live.
Creating many tiny environments for convenience. Each adds management overhead, may add networking cost and complexity, and prevents private service-to-service calls between apps. Use separate environments for real isolation needs, not just to tidy up.
6Container Apps, Containers and Sidecars
A single app can be one container or several that work as a team.
Defining a container app
For each container app you specify the image to run and where it lives, the processing power and memory each replica should receive, environment settings, secrets, ingress rules, scaling rules and health checks. Resource sizes are chosen from supported combinations of virtual CPU and memory. Giving each replica too little causes slowness or crashes; giving too much wastes money.
Multiple containers in one replica
A replica can hold more than one container. These containers share the same network address and can share temporary storage, so they can talk to each other as if they were on the same machine. The common patterns are:
Sidecar
A helper container that runs alongside the main one for the whole life of the replica, such as a log shipper, a proxy or a monitoring agent.
Init Container
A container that runs first and must finish before the main container starts, used for preparation such as fetching configuration or waiting for a dependency.
Main Container
The container holding your actual application logic and serving the traffic.
A restaurant table is the replica. The chef is the main container, the waiter who carries messages in and out is the sidecar, and the kitchen assistant who prepares ingredients before service starts is the init container. They are different people with different jobs, but they work in the same restaurant.
Statelessness is the golden rule
A replica can be started, stopped, moved or replaced at any time, for example during scaling or platform maintenance. Therefore the files written inside a container are not durable. Design your apps so that anything important lives outside, in a database, a storage account, a cache or a message queue. Temporary storage exists for scratch work, and mounted file shares can provide persistence when needed, but your application logic should assume a replica can vanish at any moment.
Saving uploaded files or user sessions in the container’s own file system. When the platform replaces or adds replicas, that data is lost or invisible to other copies. Keep state in shared external services.
7Revisions: Safe Versioning and Traffic Splitting
Revisions turn risky releases into controlled, reversible experiments.
What a revision is
A revision is an immutable snapshot of a container app at a point in time. Immutable means it cannot be edited after creation. When you change certain settings, such as the image or the container definition, the platform creates a new revision instead of altering the old one. Changes that only affect traffic, such as ingress rules or secrets, generally do not create a new revision.
Revision modes
| Mode | Behaviour | When to Use |
|---|---|---|
| Single | Only one active revision at a time. A new revision replaces the old once it is ready and healthy. | Simple apps, most everyday releases |
| Multiple | Several revisions can be active together, and you decide what share of traffic each receives. | Canary releases, blue-green deployment, A/B tests |
Rolling out without downtime
In single mode, the platform starts the new revision first, waits until it passes its health checks, shifts traffic across, and only then shuts the old revision down. Users do not see an interruption. If the new revision never becomes healthy, the old one keeps serving, so a bad release does not take the app down.
Traffic splitting patterns
Canary release
Send a small share of traffic, perhaps five percent, to the new revision. Watch error rates and delay. If healthy, gradually increase the share until it carries everything.
Blue-green deployment
Run the old revision (blue) and the new revision (green) together. Test green with a private label address, then switch all traffic at once. If something goes wrong, switch back instantly.
A/B testing
Show two versions of a feature to different groups of users and compare outcomes to decide which performs better.
flowchart LR
U[Users] --> IN[Ingress]
IN -->|90 percent| R1[Revision 1 stable]
IN -->|10 percent| R2[Revision 2 canary]
R1 --> M[Monitoring]
R2 --> M
M --> D{Healthy?}
D -->|Yes| P[Increase share of Revision 2]
D -->|No| B[Send all traffic back to Revision 1]
Labels and rollback
Revisions can be given labels, which are friendly names that create a stable address for testing a specific revision without sending real users to it. Rolling back is as simple as pointing traffic at an earlier revision, because old revisions remain available until you remove them. Old inactive revisions are kept up to a limit, so you can return to a known good state quickly.
Name your revisions with meaningful suffixes such as the release number or date. When an incident happens at night, readable names help the on-call engineer identify and roll back the right version quickly.
8Scaling: From Zero to Many and Back
Automatic scaling is the signature feature, and understanding its rules prevents most performance surprises.
Replica count limits
Every app has a minimum and maximum number of replicas. Setting the minimum to zero means the app can shut down completely when idle, costing nothing in compute while quiet. Setting it to one or more keeps an instance always ready, avoiding delays on the first request. The maximum is a safety ceiling that caps cost and protects downstream systems from being overwhelmed.
Scale rules and KEDA
Scaling decisions are driven by rules. The platform uses KEDA, which stands for Kubernetes Event-driven Autoscaling, to watch signals and adjust replica counts. A rule says “measure this signal, and if it passes this threshold, add replicas.” Several rules can exist together, and the app scales to satisfy whichever demands the most replicas.
HTTP Concurrency
Add replicas when the number of simultaneous requests per replica exceeds a chosen value. The natural choice for web apps and APIs.
TCP Connections
Scale on the number of concurrent connections, useful for services that are not plain HTTP.
Queue or Event Length
Scale on how many messages are waiting in a queue or stream, such as Azure Service Bus or Storage queues. The natural choice for background workers.
CPU and Memory
Scale when processor or memory use is high. These rules cannot scale to zero, since an idle app produces no usage to measure.
Custom Scalers
Use any of the many KEDA-supported sources, such as databases, monitoring systems or cloud streams, through custom rules.
The scaling loop
Observe
The scaler polls the signal on a regular schedule, such as the number of waiting messages or current requests.
Calculate
It divides the observed load by the target value per replica to estimate how many replicas are needed.
Adjust
Replicas are added or removed within the minimum and maximum limits.
Settle
A cool-down period passes before scaling in, so the app does not bounce up and down with every brief change.
Think of a supermarket manager watching the queue. When more than four people wait per open till, a new cashier is called. When the queues vanish and stay empty for a while, cashiers go on break. At closing time, no cashiers are needed at all.
Cold starts
When an app is scaled to zero and a request arrives, the platform must start a replica before it can respond. That startup delay is called a cold start. It includes pulling the image if not cached, starting the container and waiting for the application to become ready. For background workers and internal tools this is usually acceptable; for latency-sensitive user-facing APIs you may keep a minimum of one replica to avoid it.
Setting the maximum replica count very high without checking downstream limits. If a database can serve a hundred connections, letting an app scale to five hundred replicas, each opening several connections, will overwhelm the database and cause the very outage scaling was meant to prevent.
9Ingress, Traffic and Service Discovery
How requests find their way to the right replica.
What ingress does
Ingress is the entry gate. When enabled for an app, the platform gives it a stable address and routes incoming requests to healthy replicas, spreading load among them. Behind the scenes an Envoy-based proxy performs the routing, terminates secure connections and understands HTTP and gRPC, a fast protocol popular for internal services.
External versus internal
External ingress
The app is reachable from the public internet through an address the platform provides, or through your own custom domain. Typical for web front ends and public APIs.
Internal ingress
The app is reachable only from other apps within the environment or its connected network. Typical for back-end services that must never be exposed to the world.
No ingress
The app does not accept inbound requests at all. It only pulls work from queues or runs on schedules. Typical for background workers.
Service discovery between apps
Inside an environment, one app can call another by its simple name, and the platform resolves that name to the target app’s healthy replicas. You never need to track individual replica addresses, which change constantly as scaling occurs.
Secure connections and custom domains
External ingress is served over HTTPS by default using platform-managed certificates for the default domain. You can attach your own custom domain, and either supply your own certificate or use a managed certificate where supported. You can also restrict access by allowing only specific source address ranges, and configure features such as cross-origin sharing rules so browsers can call your API from permitted sites.
sequenceDiagram
participant U as User Browser
participant E as Envoy Ingress
participant W as Web App Replica
participant A as Orders API Replica
participant D as Database
U->>E: HTTPS request
E->>W: Route to healthy replica
W->>A: Call internal service by name
A->>D: Query data
D-->>A: Result
A-->>W: Response
W-->>E: Page content
E-->>U: HTTPS response
Expose as little as possible. Make only the front door external and keep every other service internal. Each public endpoint is another place that must be secured, throttled and monitored.
10Networking and Virtual Network Integration
Connecting your apps privately to the rest of your cloud and on-premises world.
The default network
By default, an environment is given a platform-managed network. Apps can reach public internet services and public endpoints of Azure services, and external apps are reachable through the public address. This is quick to start with and perfectly suitable for many projects.
Bringing your own virtual network
For stricter requirements, you can place an environment inside a virtual network that you control. A virtual network is your private network space in Azure, divided into subnets. Doing this lets apps reach private databases, other virtual machines and on-premises systems over private connections, and lets you control and inspect outgoing traffic with firewalls and route rules. The subnet you dedicate to the environment needs enough address space for growth, and the choice is best made at creation because changing it later can be difficult.
Public or private environment
| Style | Inbound Traffic | Typical Use |
|---|---|---|
| External environment | Apps with external ingress are reachable from the internet | Public websites and APIs |
| Internal environment | Only reachable from inside the virtual network, via private addresses | Internal line-of-business systems, strict compliance |
Private connectivity to other services
Private endpoints let Azure services such as databases and storage appear as private addresses inside your network, so traffic never crosses the public internet. Combined with virtual network integration, they allow a design where the only public entry point is a carefully protected gateway, while everything behind it stays private.
Front doors and gateways
Many production designs place a web application firewall, through a gateway or a global front door service, in front of external container apps. It can filter malicious requests, provide global routing and add extra protection and caching. This layered approach means the container app itself is not the first line of defence.
flowchart TD
U[Internet Users] --> FD[Front Door or Gateway with web firewall]
FD --> ENV[Container Apps Environment inside virtual network]
ENV --> WEB[Web App external ingress]
WEB --> API[Orders API internal ingress]
API --> PE[Private Endpoint]
PE --> DB[(Database)]
ONP[On-premises systems] -.VPN or private circuit.-> ENV
Choosing a subnet that is too small, or leaving networking decisions until after production launch. Network choices are among the hardest to change later. Plan address space and public versus private exposure at the very beginning.
11Jobs: Running Containers to Completion
Not every workload serves requests forever. Many just do a task and finish.
Apps versus jobs
A container app is expected to run continuously, or at least to stay available to answer requests. A job is a container that starts, performs a defined piece of work and then stops. When it finishes, it releases its resources and you pay only for the time it ran. Examples include generating a nightly report, processing a batch of uploaded files, running database maintenance and training a small model.
Trigger types
Manual
A person or another system starts the job on demand, such as a one-time data migration.
Schedule
The job starts at recurring times defined by a schedule expression, like every night at two o’clock.
Event-driven
The job starts in response to events, such as messages arriving in a queue, using the same scaling machinery as apps.
Parallelism and retries
A job execution can run several replicas in parallel and can require a certain number of them to complete successfully. You can set a retry limit so that failed attempts are tried again, and a timeout so a stuck job does not run forever and cost money. This makes jobs suitable for splitting a large task into many small pieces processed together.
A container app is a shopkeeper who stays at the counter all day. A job is a contractor who arrives, finishes one painting task and leaves. You pay the shopkeeper for time on duty and the contractor only for the hours worked.
Make job work idempotent, meaning running it twice has the same result as running it once. Retries and overlapping schedules can then never corrupt your data.
12Microservices Helpers: Dapr and Event-Driven Design
Distributed applications share common problems. Dapr offers ready-made answers.
The distributed application problem
When an application is split into many services, every team faces the same recurring challenges: how services call each other safely and retry on failure, how they publish and receive events, how they store state, how they fetch secrets and how they trace a request across several services. Solving each of these separately in every service wastes effort and creates inconsistency.
What Dapr is
Dapr, short for Distributed Application Runtime, is an open source project that provides building blocks for these common tasks. Each service runs next to a small helper process, a sidecar, that exposes simple standard interfaces. Your code talks to its local helper, and the helper handles the details of talking to the actual messaging system, database or secret store. Because you ask for a capability rather than a specific product, you can change the underlying technology with a configuration change rather than a rewrite.
Service Invocation
Call other services by name with retries and secure communication handled for you.
Publish and Subscribe
Send events to a topic without knowing who listens, enabling loose coupling.
State Management
Save and read small pieces of state through a uniform interface, backed by a store you choose.
Bindings
Trigger your code from external systems or send data out to them with simple connectors.
Secrets
Retrieve secrets from a secure store at run time instead of embedding them.
Dapr is like a personal assistant sitting beside each employee. The employee says “send this letter to the accounts team” and the assistant figures out whether to use email, post or courier. If the company changes its delivery method tomorrow, the employee’s request stays exactly the same.
Event-driven architecture
Container Apps shines in event-driven designs. A producer places a message on a queue and moves on. Worker apps scale up automatically when messages pile up and scale to zero when the queue is empty. Because the producer and consumers are decoupled, each can fail, scale and be updated independently. This pattern absorbs sudden bursts smoothly: the queue holds the surge, and workers drain it at a sustainable pace.
flowchart LR
FE[Web Front End] -->|place order| Q[(Message Queue)]
Q --> W1[Worker replica 1]
Q --> W2[Worker replica 2]
Q --> W3[Worker replica N scales with queue length]
W1 --> DB[(Orders Database)]
W2 --> DB
W3 --> DB
W3 --> EV[Publish OrderProcessed event]
Dapr is optional. Many successful applications on Container Apps never use it. Adopt it when its building blocks solve a real problem you have, not simply because it is available.
13Images, Registries and Deployment
Getting your container from a developer’s laptop to a running app.
Where images are stored
Container Apps pulls images from a registry. Azure Container Registry is the natural choice inside Azure, offering private storage, scanning options, geographic replication and tight integration with Azure identity. Public registries can also be used, and other private registries are supported with credentials. For production, a private registry that you control reduces the risk of tampered or unavailable images.
The path to production
Build
The pipeline packages the application into an image with a unique, meaningful tag such as the commit identifier.
Scan and test
Automated tests run, and the image is scanned for known vulnerabilities in its libraries and base layers.
Push
The approved image is stored in the registry.
Deploy a revision
The container app is updated to reference the new image, which creates a new revision.
Shift traffic
Traffic moves gradually or immediately to the new revision, guided by health checks and monitoring.
Ways to deploy
You can deploy through the Azure portal for learning, command-line tools for scripting, and declarative templates such as Bicep or ARM, or tools like Terraform, for repeatable infrastructure. Continuous integration and delivery systems, including GitHub Actions and Azure DevOps, can build images and update apps automatically on every approved change. There is also a convenient path that builds an image directly from source code, so teams without container experience can still get started, though mature teams usually prefer explicit, reviewed image builds.
Image hygiene
Use small base images
Smaller images start faster, cost less to store and transfer, and have fewer components that could contain vulnerabilities.
Never use a moving tag in production
A tag like “latest” can point to different images over time, making deployments unpredictable. Use unique, immutable tags or digests.
Keep secrets out of images
Anything baked into an image can be extracted by anyone with access to the image. Supply secrets at run time instead.
Smaller images also reduce cold start time, because less data must be downloaded before a new replica can begin. Trimming an image is a cheap way to improve responsiveness.
14Configuration, Secrets and Storage
Keeping settings flexible and sensitive data safe.
Environment variables and secrets
Applications need settings that differ between environments, such as addresses of databases or feature switches. These are supplied as environment variables rather than being hard-coded. Sensitive values such as passwords and keys are stored as secrets, which the platform keeps protected and lets containers reference. Because secrets are not part of the image, the same image can be used in every stage with different secret values.
Key Vault references
For stronger control, secrets can be held in Azure Key Vault, a dedicated secure store with detailed access control, auditing and rotation features. Container apps can reference Key Vault entries so the actual value is kept centrally and updated in one place. This is the recommended approach for sensitive material in production.
Managed identity: the best secret is no secret
A managed identity is an identity that Azure creates for your app so it can prove who it is to other Azure services, without any password. You grant the identity permission to read from a storage account, a key vault or a database, and the platform handles the tokens behind the scenes. It removes the entire class of problems where credentials leak, expire or are forgotten in configuration files. Managed identity can also be used to pull images from a private registry.
A secret is a physical key you must copy, hide and replace if lost. A managed identity is a door that recognises your face. Nothing exists to steal, copy or forget under a doormat.
Storage options
| Storage Type | Lifetime | Shared Across Replicas? | Typical Use |
|---|---|---|---|
| Container file system | Lost when the replica restarts | No | Small scratch data inside one container |
| Ephemeral volume | Lives as long as the replica | Shared by containers within one replica | Temporary files shared between main and sidecar containers |
| Azure Files share | Persistent | Yes, can be mounted by many replicas | Shared documents, configuration files, simple persistence |
| External services | Persistent and managed separately | Yes | Databases, blob storage, caches: the preferred home for important data |
Using a mounted file share as a database. File shares are convenient but slower than dedicated data services and are not designed for heavy concurrent database-style access. Use a real database for structured, frequently changing data.
15Health Probes and Reliability
Teaching the platform how to tell whether your app is truly well.
Why probes exist
A process that is running is not necessarily working. It may be stuck waiting for a lock, still loading data or unable to reach its database. Health probes are small checks the platform performs on each replica, so it can make smart decisions about restarting it or sending it traffic.
Startup Probe
Asks “has the app finished starting?” Other probes wait until this one succeeds, giving slow-starting apps time to initialise without being killed.
Readiness Probe
Asks “is the app ready to receive traffic right now?” A replica that fails is temporarily removed from the routing pool but not killed.
Liveness Probe
Asks “is the app still alive, or deadlocked?” A replica that fails repeatedly is restarted.
A hospital nurse performs three kinds of checks. Did the patient wake up after the operation (startup)? Is the patient well enough to receive visitors (readiness)? Is the patient responsive or does the doctor need to be called to intervene (liveness)?
Designing good probes
A readiness check should confirm that the app can do its real work, which sometimes means checking critical dependencies. A liveness check, however, should usually be shallow. If a liveness probe fails whenever the database is slow, the platform will restart every replica at once during a database hiccup, turning a small problem into a total outage. Separating the questions “can I serve traffic?” and “do I need restarting?” is one of the most valuable reliability habits.
Graceful shutdown
When a replica is removed, the platform asks the application to stop and gives it a short window to finish in-flight work. Well-written apps catch the stop signal, stop accepting new requests, complete current ones and close connections cleanly. Apps that ignore it are forcibly terminated, which can cut requests in half and leave work unfinished.
Problem
The liveness probe checks the database connection and downstream services as well as the app itself.
Why It’s Harmful
When a dependency slows down, every replica fails its liveness check and is restarted together. The restarts add load and delay, prolonging the incident and removing all capacity at the worst moment.
Correct Approach
Keep liveness checks shallow and focused on whether the process itself is responsive. Put dependency checks in the readiness probe so unhealthy replicas simply pause receiving traffic rather than being restarted.
16Security for Container Apps
Microsoft secures the platform; you secure your application, images, identities and exposure.
Shared responsibility
Because the service is managed, Microsoft handles the underlying infrastructure, including patching of the hosts and the platform components. You remain responsible for the contents of your container images, your application code, the identities and permissions you grant, the secrets you handle and which endpoints you expose.
Layers of protection
Supply Chain
Use trusted base images, scan images for vulnerabilities, sign them where possible, and pull only from controlled registries.
Identity
Prefer managed identities, grant the least privilege needed, and separate identities per app.
Network
Use internal ingress by default, private endpoints for data services, firewalls and a web application firewall in front of public apps.
Secrets
Store secrets in a vault, rotate them regularly and never place them in images or source code.
Authentication
Use built-in authentication features to require sign-in through identity providers before requests ever reach your code.
Container Hardening
Run as a non-administrative user, avoid unnecessary tools in images and keep the file system as locked-down as practical.
Built-in authentication
Container Apps offers a built-in authentication feature, often called Easy Auth, that sits in front of your app. It can require users to sign in with identity providers such as Microsoft Entra ID or other supported providers before any request reaches your container. This saves you from writing sign-in code for simple scenarios, though complex authorisation rules still belong in your application.
Peer-to-peer encryption
Traffic between apps inside an environment can be encrypted so that even internal conversations are protected on the wire. Combined with internal-only ingress, this limits what an attacker could observe or reach after getting a foothold.
Problem
Every service in the system has external ingress so that developers can test each one directly.
Why It’s Harmful
Each exposed service is a public attack surface. Internal APIs often lack the protections of a public front door, and attackers can bypass the controls placed on the main entry point.
Correct Approach
Expose only a single hardened front door. Keep other services on internal ingress, and give developers private access through VPN, bastion hosts or separate non-production environments.
17Monitoring, Logging and Troubleshooting
Containers appear and vanish quickly, so centralised observation is essential.
Why central logging matters
A replica’s own storage disappears when it is removed, taking local log files with it. Replicas also come in large numbers, so reading logs one at a time is impractical. The platform therefore captures what your containers write to standard output and standard error, along with platform system events, and sends them to the logging destination chosen for the environment.
The three signals
Metrics
Numbers over time, such as replica count, requests, processor use, memory, restarts and network traffic. They are ideal for dashboards and alerts.
Logs
Detailed text records of what the application and platform did. They explain why something happened and are searched with a query language in the log workspace.
Traces
End-to-end records of a single request travelling through many services, showing where time was spent. They are collected through application instrumentation, commonly with Application Insights or open standards.
Useful platform features
Besides logs and metrics, you can stream live console output while debugging, open a diagnostic console inside a running replica for investigation, and use built-in diagnostic tools that detect common problems such as failed starts or scaling issues. System logs reveal events such as image pull failures, probe failures and scaling decisions, which are often the quickest route to the cause of a puzzling issue.
A troubleshooting routine
Is a replica running?
Check the revision status and replica count. A revision that never becomes ready usually points to an image, probe or configuration problem.
Read the system logs
Look for image pull errors, authorisation failures against the registry, out-of-memory kills and probe failures.
Read the application logs
Find stack traces, connection errors and warnings written by your own code.
Check scaling and limits
Confirm whether the app is stuck at its maximum replicas, hitting memory limits or being throttled.
Verify dependencies
Test that databases, queues and other services are reachable, permitted by firewalls and responding in good time.
Write logs in a structured format, such as one JSON object per line, with request identifiers. Searching and correlating structured logs across dozens of replicas is far easier than reading free-form text.
Logging too verbosely in production. Log storage is billed by volume, and a chatty app multiplied by many replicas can generate a surprising bill and bury the useful messages in noise.
18Pricing and Cost Optimisation
Understanding what you pay for turns a flexible platform into a predictable bill.
The consumption model
On the consumption profile, you are billed for the resources your replicas use, measured in virtual CPU and memory over time, plus a charge related to the number of requests received. Replicas that are idle can be billed at a reduced rate when they are only holding memory, and an app scaled to zero incurs no compute charge. A monthly free allowance of resources and requests is typically included for each subscription, which makes small and experimental apps very cheap. Exact rates change and differ by region, so always check the current Azure pricing page before budgeting.
The dedicated model
On dedicated workload profiles, you pay for the machines in the profile for as long as they exist, and you pack your apps onto them. This can be more economical for steady, heavy workloads that would otherwise use the consumption model constantly, and it provides predictable capacity. There is also an additional management charge for the environment when dedicated profiles are used. The trade-off is that you lose the pure pay-for-use nature, since you pay for the capacity you reserve whether or not you fill it.
| Situation | Likely Better Fit | Reason |
|---|---|---|
| Spiky or unpredictable traffic | Consumption | Pay only for what is used, and scale to zero when idle |
| Rarely used internal tool | Consumption | Nearly free when idle |
| Constant heavy load all day | Dedicated, possibly with commitments | Reserved capacity may cost less than metered usage |
| Need special hardware | Dedicated (memory or GPU) | Only dedicated profiles offer those machines |
Other costs to remember
Logging
Log ingestion and retention in the workspace are billed separately and can grow quickly.
Registry
Storing images and replicating them across regions has a cost.
Networking
Data leaving Azure, gateways, firewalls and private endpoints each add charges.
Dependencies
Databases, queues, caches and storage typically cost more than the compute that uses them.
Optimisation habits
Right-size replicas
Measure real processor and memory use, then choose the smallest allocation that is comfortably safe. Oversized replicas multiply waste across every copy.
Scale to zero where acceptable
Use zero minimum replicas for workers, internal tools and development environments.
Cap the maximum
Protect against runaway scaling and accidental traffic floods by setting sensible ceilings.
Control logging volume
Log at suitable levels and set retention periods that match real needs.
Review old revisions and resources
Remove unused apps, environments and images, and use budgets with alerts to catch surprises early.
Assuming serverless always means cheapest. For a service that is busy around the clock, metered consumption may exceed the cost of reserved capacity. Compare both models using real usage numbers, not guesses.
19Container Apps Compared with Other Azure Compute Options
The right tool depends on how much control and how much convenience you need.
| Service | Control Level | Operational Burden | Best For |
|---|---|---|---|
| Virtual Machines | Complete: you manage the operating system | High | Legacy software, special requirements, full control |
| Azure Kubernetes Service | Very high: direct access to Kubernetes | Medium to high | Complex platforms, custom operators, large teams with Kubernetes skills |
| Azure Container Apps | Moderate: containers and scaling rules without cluster management | Low | Microservices, APIs, workers, event-driven apps, jobs |
| App Service | Lower: code or container on a managed web platform | Low | Conventional web apps and APIs with simple needs |
| Azure Functions | Lowest: small functions triggered by events | Very low | Short event-driven tasks and glue logic |
| Container Instances | Basic: single containers or small groups | Low | Simple, short-lived container runs without scaling logic |
Choosing between neighbours
Container Apps versus AKS
Choose Container Apps when you want containers, scaling and microservice features without running a cluster. Choose AKS when you need Kubernetes itself: custom resources, operators, specific networking plug-ins or full cluster control.
Container Apps versus App Service
App Service is a mature choice for straightforward web apps. Container Apps adds scale to zero, event-driven scaling, jobs, sidecars, traffic splitting between revisions and Dapr, making it stronger for microservice and worker designs.
Container Apps versus Functions
Functions favours tiny units of code triggered by events. Container Apps suits larger services, long-running processes and custom runtimes. Azure Functions can also be hosted on Container Apps for teams who want that combination.
Virtual machines are building your own car from parts. AKS is leasing a high-performance car you must service yourself. Container Apps is a car-sharing service with the vehicle size chosen for each trip. App Service is a taxi with fixed routes. Functions is a courier taking one parcel at a time.
If you do not already know why you need direct Kubernetes access, you probably do not need it. Start with the simpler managed option and move up only when a real limitation appears.
20Advantages, Limitations and Trade-offs
An honest view of both sides leads to better decisions.
Advantages
- No cluster to build, patch or upgrade; Microsoft runs the underlying platform.
- Scale to zero and event-driven scaling reduce cost for quiet or bursty workloads.
- Revisions make rolling updates, canary releases and rollbacks simple.
- Built-in ingress, service discovery, secrets and managed identity cover most common needs.
- Supports any language, framework or runtime that can be containerised.
- Jobs and workers sit comfortably beside web apps in the same environment.
Disadvantages / Trade-offs
- No direct access to the Kubernetes API, so custom operators and deep cluster tuning are unavailable.
- Cold starts can add delay when apps are scaled to zero.
- Some network and environment choices are hard to change after creation.
- Platform limits on sizes, replica counts and features apply and evolve over time.
- Teams still need container skills, good image hygiene and sound distributed-systems design.
When it is not the right tool
Avoid Container Apps if your software cannot be containerised, if it requires privileged access to the host operating system, if you depend on specific Kubernetes extensions, or if you need guaranteed ultra-low latency with no possibility of a startup delay and cannot afford any minimum capacity. For those cases, virtual machines or a full Kubernetes cluster are more appropriate.
21Real-World Scenarios and a Reference Architecture
Patterns are clearer when applied. These examples are typical industry uses, described generally.
E-commerce platform
A retailer splits its shop into catalogue, cart, checkout and notification services. The web front end is external; the rest are internal. During sales, checkout and worker apps scale quickly with demand, and order messages are buffered in a queue so spikes never overwhelm the database.
Document processing pipeline
Users upload invoices to storage. An event triggers workers that extract and validate data. Workers scale with the number of waiting files and fall to zero overnight, so the company pays only while documents are actually being processed.
Internal reporting jobs
A finance team runs nightly and month-end reports as scheduled jobs. Each job starts, produces its output, writes it to storage and stops, costing nothing in between.
Machine learning inference
A team packages a trained model behind an API and runs it on a GPU-capable dedicated profile, while the lightweight gateway and preprocessing services run on consumption capacity in the same environment.
Safe experimentation for a product team
A product team ships new features to five percent of users using revision traffic splitting, compares error rates and conversions, and expands or reverts without redeploying anything.
A reference architecture
The design below combines the ideas from earlier chapters for a typical business application: one hardened public entry point, private internal services, queue-driven workers, protected data services and central monitoring.
flowchart TD
USER[Users] --> FD[Front Door with web firewall]
FD --> WEB[Web App external ingress min 1 replica]
WEB --> API[Orders API internal ingress]
API --> DB[(Managed Database via Private Endpoint)]
API --> SB[(Service Bus Queue)]
SB --> WRK[Worker App scales to zero with queue length]
WRK --> DB
JOB[Nightly Job on schedule] --> DB
KV[Key Vault] -.managed identity.-> API
KV -.managed identity.-> WRK
ACR[Container Registry] -.image pull.-> WEB
ACR -.image pull.-> API
ACR -.image pull.-> WRK
LAW[Log Analytics and Application Insights] -.collects.-> WEB
LAW -.collects.-> API
LAW -.collects.-> WRK
Walking through the design
One hardened front door
Only the gateway and web app are reachable from outside. The firewall filters malicious traffic before it reaches any container.
Private services
The API has internal ingress and speaks to the database through a private endpoint, so sensitive traffic never touches the public internet.
Decoupling with a queue
The API places work on a queue. Workers scale with queue length, absorbing bursts and sleeping when quiet.
Identity instead of passwords
Apps use managed identities to read secrets and pull images, so no long-lived credential is stored anywhere.
Observability from day one
Every app sends logs, metrics and traces to central workspaces, with alerts on errors, restarts and queue backlog.
Why this works
Each risk has a specific answer. Traffic spikes are handled by scaling and buffering. Bad releases are contained by revisions and traffic splitting. Credential theft is minimised by managed identities. Cost is controlled by scale to zero for workers and right-sized replicas. Data is protected by private networking and external managed storage, so replicas stay disposable.
22Best Practices and Common Mistakes
Habits that separate smooth production systems from fragile ones.
Best practices
Design stateless
Keep all durable data outside containers so any replica can be replaced at any time.
Use managed identity
Prefer identity-based access to secrets, data and registries over stored passwords.
Set resource requests carefully
Base processor and memory sizes on measurements, and test under load before launch.
Configure all three probes
Give the platform an accurate picture of startup, readiness and liveness.
Pin image versions
Use unique tags or digests so every deployment is traceable and repeatable.
Automate everything
Describe infrastructure in templates and ship through reviewed pipelines.
Handle shutdown signals
Finish in-flight work and close connections cleanly when a replica is stopped.
Load test scaling
Confirm that scale rules actually react in time, and that downstream systems survive the extra replicas.
Common mistakes at a glance
| Mistake | Consequence | Better Habit |
|---|---|---|
| Storing state in the container | Lost or inconsistent data across replicas | Use databases, storage and caches |
| Using the “latest” image tag | Unpredictable deployments and difficult rollbacks | Use unique, immutable tags |
| Exposing every service publicly | Large attack surface | Internal ingress by default |
| No maximum replica limit | Runaway cost and overwhelmed dependencies | Set safe ceilings |
| Deep liveness checks | Mass restarts during dependency slowness | Shallow liveness, deeper readiness |
| Secrets in images or source code | Leaked credentials | Vault references and managed identity |
| Skipping monitoring | Blind incident response | Central logs, metrics, traces and alerts from day one |
Problem
A team builds one giant container holding the web server, background processing, scheduler and several unrelated services, and runs it as a single app.
Why It’s Harmful
Everything must scale together, so a heavy background task forces extra copies of the whole bundle. A bug in one part can bring down all parts, and releases become large and risky.
Correct Approach
Split by responsibility. Run the web app, workers and scheduled tasks as separate apps and jobs, each with its own scaling rules, resources and release cycle.
Problem
A team splits a simple application into dozens of tiny services before it has any real scaling or organisational need.
Why It’s Harmful
Network calls replace simple function calls, failures multiply, debugging becomes harder and the team spends more time on plumbing than on features.
Correct Approach
Start with fewer, larger services and split only when a clear need appears, such as different scaling profiles, different release speeds or separate team ownership.
23Frequently Asked Questions
No. The platform hides the Kubernetes layer. You work with apps, revisions, replicas and scaling rules. Understanding container basics is enough to begin, though knowing Kubernetes ideas can help you grasp why things behave as they do.
On the consumption profile, an app scaled to zero replicas incurs no compute charge. Other resources such as logging, registry storage and dependencies still cost money, so the total bill is not necessarily zero.
That is a cold start. The platform must create a replica, pull the image if needed, start the container and wait for readiness. Keeping a minimum of one replica and using small images reduces or removes the delay.
A revision is an immutable version of your app’s definition. A replica is one running copy of a revision. One revision may run as many replicas, depending on scaling.
Deploy a new revision, let it pass health checks, and shift traffic gradually using multiple revision mode. Watch errors and delay, and revert traffic to the earlier revision if anything looks wrong.
Yes. Apps in the same environment can call each other by name through internal ingress, and traffic can be encrypted between them. Apps in different environments are isolated unless you connect them deliberately.
Use blob storage or a database for important data. Use a mounted file share when you need a shared file system, and treat local container storage as temporary only.
Use managed identities so your app authenticates to Azure services without credentials, and use Key Vault references for any secret you cannot avoid.
KEDA is an open source project that scales workloads based on events and metrics, such as queue length. Container Apps uses it so your workers can grow with the backlog and shrink to zero when empty.
No. It is an optional helper that provides ready-made building blocks for service calls, events, state and secrets. Use it where it simplifies your design.
Choose Azure Kubernetes Service when you need direct Kubernetes control, such as custom operators, specialised networking components or very fine tuning of the cluster, and have the skills to run it.
Yes. Jobs can run on a schedule, on demand or in response to events, run to completion and then release resources.
Place the environment in your own virtual network and reach the database through a private endpoint or private network path, so traffic stays off the public internet.
Common causes are image pull failures from authorisation or tag problems, the container exiting because of missing configuration, failing startup or readiness probes, and insufficient memory. System logs usually show which one it is.
Right-size replicas, set maximum replica counts, scale to zero where acceptable, control log volume, remove unused resources and set budgets with alerts.
Yes, when designed properly with zone redundancy where available, sound health probes, private networking, managed identities, monitoring and a tested deployment process. Always verify current service limits and agreements in Microsoft’s documentation.
24Summary and Key Takeaways
Azure Container Apps lets you run containers without running the cluster underneath them. You package your application as an image, describe how much power it needs and how it should scale, and the platform takes care of placement, networking entry, restarts and rolling updates. Environments group related apps, revisions give safe versioning and traffic splitting, replicas provide capacity, jobs handle tasks that finish, and scaling rules driven by requests or events let you grow quickly and shrink to nothing. The simplicity comes with trade-offs: you give up direct Kubernetes access, and you must still design stateless apps, secure identities, sensible networking and careful monitoring. Used for the right workloads, it removes a large amount of operational effort and lets small teams ship reliable, cost-aware systems.
Key Takeaways
- It is serverless containers — you supply the image and the rules; Microsoft runs the servers and the Kubernetes-based platform beneath.
- Learn six words — environment, container app, revision, replica, job and ingress explain almost everything in the service.
- Scale on the right signal — use request concurrency for web apps and queue length for workers, set sensible minimums and maximums, and plan for cold starts.
- Release with revisions — canary, blue-green and instant rollback make deployments low-risk when combined with health checks and monitoring.
- Stay stateless and private — keep data in external services, expose only one hardened front door, and use internal ingress and private endpoints elsewhere.
- Prefer identity over secrets — managed identities and Key Vault references remove most credential risks.
- Compare costs honestly — consumption suits spiky and idle workloads, dedicated suits steady heavy ones, and logging and dependencies often cost as much as compute.