Skip to content

Commit d5d3b0b

Browse files
authored
Merge pull request #314014 from craigshoemaker/aca/connect-apps-update
[Container Apps] Update connect-apps.md to enhance clarity on inter-container communication methods
2 parents b2b17b3 + 4f5d076 commit d5d3b0b

2 files changed

Lines changed: 223 additions & 28 deletions

File tree

Lines changed: 221 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,252 @@
11
---
22
title: Communicate between container apps in Azure Container Apps
3-
description: Learn how to communicate between different container apps in the same environment in Azure Container Apps.
4-
services: container-apps
3+
description: Learn how container apps communicate within the same environment using FQDNs, app names, Dapr service invocation, and custom domains in Azure Container Apps.
54
author: craigshoemaker
6-
ms.service: azure-container-apps
7-
ms.topic: concept-article
8-
ms.date: 04/07/2025
95
ms.author: cshoe
6+
ms.service: azure-container-apps
7+
ms.topic: conceptual
8+
ms.date: 03/31/2026
9+
ai-usage: ai-assisted
1010
---
1111

1212
# Communicate between container apps in Azure Container Apps
1313

14-
Azure Container Apps exposes each container app through a domain name if [ingress](ingress-overview.md) is enabled. You can expose ingress endpoints either publicly to the world or to the other container apps in the same environment. Alternatively, you can limit ingress to only other container apps in the same [environment](environment.md).
14+
<!-- Source: Q1, Q2, Q3 -->
15+
16+
Azure Container Apps provides built-in service discovery and routing so your container apps can communicate with each other without managing infrastructure. When you deploy multiple container apps to the same [environment](environment.md), the platform handles DNS resolution, load balancing, and secure traffic routing automatically.
1517

16-
Application code can call other container apps in the same environment using one of the following methods:
18+
If [ingress](ingress-overview.md) is enabled, each container app gets a domain name. You can make that endpoint available publicly or restrict it to other container apps in the same environment. <!-- Source: Q1 -->
1719

18-
- Default fully qualified domain name (FQDN)
19-
- A custom domain name
20-
- The container app name, for instance `http://<APP_NAME>` for internal requests
21-
- A Dapr URL
20+
Container apps can reach each other through any of these methods:
21+
22+
- **Fully qualified domain name (FQDN)** : the default generated domain
23+
- **App name**: a short-form `http://<APP_NAME>` address for internal calls
24+
- **Dapr service invocation**: a sidecar-based approach with built-in retries and observability
25+
- **Custom domain**: your own domain name with a managed certificate
2226

2327
> [!NOTE]
24-
> When you call another container in the same environment using the FQDN or app name, the network traffic never leaves the environment.
28+
> When you call another container app in the same environment by using the FQDN or app name, network traffic never leaves the environment.
29+
30+
## Why it matters
31+
32+
<!-- Source: Q3, Q5 -->
2533

26-
A sample solution showing how you can call between containers using both the FQDN Location or Dapr can be found on [Azure Samples](https://github.com/Azure-Samples/container-apps-connect-multiple-apps)
34+
In a microservices architecture, services need to call each other reliably. Azure Container Apps removes the operational burden of setting up service discovery, managing DNS records, and configuring reverse proxies.
2735

28-
## Location
36+
Here's what the platform handles for you:
2937

30-
A container app's location is composed of values associated with its environment, name, and region. Available through the `azurecontainerapps.io` top-level domain, the fully qualified domain name (FQDN) uses:
38+
- **Automatic DNS registration**: Every container app gets a resolvable hostname as soon as it's deployed.
39+
- **Proxy-managed routing**: All inter-app traffic flows through a built-in Envoy proxy layer that handles TLS termination, traffic splitting, and load balancing. <!-- Source: Q3, Q5 -->
40+
- **Environment-scoped isolation**: Internal endpoints are only reachable from within the same environment, creating a natural security boundary. <!-- Source: Q1 -->
41+
- **Protocol flexibility**: Communication over HTTP/1.1, HTTP/2 (for gRPC), or raw TCP depending on your workload needs. <!-- Source: Q6 -->
3142

32-
- The container app name
33-
- The environment unique identifier
34-
- Region name
43+
These capabilities mean you can focus on your application logic rather than networking plumbing.
3544

36-
The following diagram shows how these values are used to compose a container app's fully qualified domain name.
45+
## Container app location (FQDN)
46+
47+
<!-- Source: Q2, Q4 -->
48+
49+
Each container app's fully qualified domain name is composed of the app name, a unique environment identifier, and the region. These domain fragments all fall under the `azurecontainerapps.io` top-level domain.
3750

3851
:::image type="content" source="media/connect-apps/azure-container-apps-location.png" alt-text="Azure Container Apps container app fully qualified domain name.":::
3952

53+
### External and internal FQDNs
54+
55+
<!-- Source: Q1, Q2 -->
56+
57+
The ingress visibility setting controls whether your app is reachable from outside the environment:
58+
59+
| Visibility | FQDN pattern | Reachable from |
60+
|---|---|---|
61+
| **External** | `<APP_NAME>.<ENVIRONMENT_UNIQUE_ID>.<REGION>.azurecontainerapps.io` | Anywhere (public internet) |
62+
| **Internal** | `<APP_NAME>.internal.<ENVIRONMENT_UNIQUE_ID>.<REGION>.azurecontainerapps.io` | Same environment only |
63+
64+
When you set ingress to **internal**, the FQDN includes an `.internal.` segment. Other container apps in the same environment can still reach the app using this address, but requests from outside the environment receive a `404` response from the environment's proxy. The DNS name resolves to the environment's shared IP, but the proxy rejects the request because the app is internal-only. <!-- Source: Q1 -->
65+
4066
[!INCLUDE [container-apps-get-fully-qualified-domain-name](../../includes/container-apps-get-fully-qualified-domain-name.md)]
4167

42-
### Dapr location
68+
### Revision label FQDNs
69+
70+
<!-- Source: Q11 -->
71+
72+
When you assign labels to specific revisions, each label gets its own unique FQDN using a triple-dash separator:
73+
74+
```
75+
<APP_NAME>---<LABEL>.<ENVIRONMENT_UNIQUE_ID>.<REGION>.azurecontainerapps.io
76+
```
4377

44-
Developing microservices often requires you to implement patterns common to distributed architecture. Dapr allows you to secure microservices with mutual Transport Layer Security (TLS) (client certificates), trigger retries when errors occur, and take advantage of distributed tracing when Azure Application Insights is enabled.
78+
For internal apps, the pattern includes the `.internal.` segment:
4579

46-
A microservice that uses Dapr is available through the following URL pattern:
80+
```
81+
<APP_NAME>---<LABEL>.internal.<ENVIRONMENT_UNIQUE_ID>.<REGION>.azurecontainerapps.io
82+
```
4783

48-
:::image type="content" source="media/connect-apps/azure-container-apps-location-dapr.png" alt-text="Azure Container Apps container app location with Dapr.":::
84+
Label FQDNs let you send traffic to a specific revision directly. This practice is useful for testing new versions, running A/B experiments, or providing stable endpoints for specific revision deployments. <!-- Source: Q11 -->
4985

5086
## Call a container app by name
5187

52-
You can call a container app by doing by sending a request to `http://<CONTAINER_APP_NAME>` from another app in the environment.
88+
<!-- Source: Q3, Q14 -->
89+
90+
The most straightforward way to call another container app from within the same environment is by its name. Send a request to `http://<CONTAINER_APP_NAME>`, and the environment's built-in DNS resolves the name automatically.
91+
92+
```
93+
http://my-backend-api
94+
```
95+
96+
### How DNS resolution works
97+
98+
<!-- Source: Q3 -->
99+
100+
Behind the scenes, Azure Container Apps uses a custom DNS configuration that translates container app names into routable addresses. When your app makes a request to another app's name or FQDN:
101+
102+
1. The environment's DNS server resolves the hostname to the Envoy proxy service address.
103+
1. The Envoy proxy identifies the target app from the original hostname.
104+
1. The proxy routes the request to the correct revision(s) based on your traffic configuration.
105+
106+
This architecture means container apps never communicate directly with each other's pods. All traffic passes through the proxy layer, which provides TLS termination, load balancing, and traffic splitting. <!-- Source: Q3, Q5, Q14 -->
107+
108+
> [!TIP]
109+
> Use the short app name (`http://<APP_NAME>`) for calls between container apps in the same environment. It's simpler than the full FQDN and works the same way since the DNS resolves both patterns through the same proxy.
110+
111+
## Transport protocols
112+
113+
<!-- Source: Q6 -->
114+
115+
Container apps support three transport modes for ingress, configured through the `transport` property:
116+
117+
| Transport | Use case | Details |
118+
|---|---|---|
119+
| **Auto** (default) | Standard web APIs and services | Negotiates HTTP/1.1 and HTTP/2 automatically |
120+
| **HTTP/2** | gRPC services | Enables HTTP/2 end-to-end, required for gRPC |
121+
| **TCP** | Non-HTTP protocols (databases, custom protocols) | Raw TCP connections with port mapping |
122+
123+
> [!NOTE]
124+
> External TCP ingress requires a [custom VNet](networking.md). If you try to create an external TCP app without a custom VNet, you receive a `ContainerAppTcpRequiresVnet` error. Internal TCP ingress works without a custom VNet.
125+
126+
When you use TCP transport, you can also expose extra ports beyond the primary ingress port. Each extra port creates a separate TCP endpoint that other apps in the environment can connect to. <!-- Source: Q13 -->
127+
128+
## Traffic splitting and revision routing
129+
130+
<!-- Source: Q12 -->
131+
132+
Azure Container Apps supports three revision modes that affect how traffic is distributed between container apps:
133+
134+
| Mode | Behavior |
135+
|---|---|
136+
| **Single** | All traffic goes to the latest active revision. |
137+
| **Multiple** | Traffic splits across revisions by percentage, based on your traffic rules. |
138+
| **Labels** | Each labeled revision gets a unique FQDN for direct access. |
139+
140+
In **multiple** mode, when another container app calls your app's FQDN, the proxy automatically distributes requests across revisions according to your configured weights. In **labels** mode, callers can target a specific revision using its [label FQDN](#revision-label-fqdns).
141+
142+
For more information, see [Revisions in Azure Container Apps](revisions.md).
143+
144+
## Dapr service invocation
145+
146+
<!-- Source: Q7, Q8, Q9 -->
147+
148+
[Dapr](https://docs.dapr.io) (Distributed Application Runtime) provides a sidecar-based approach to inter-app communication. By enabling Dapr, your container apps gain built-in service invocation with mutual TLS, automatic retries, and distributed tracing through Azure Application Insights.
149+
150+
:::image type="content" source="media/connect-apps/azure-container-apps-location-dapr.png" alt-text="Diagram showing Azure Container Apps container app location with Dapr.":::
53151

54-
## Next steps
152+
### How Dapr invocation works
153+
154+
<!-- Source: Q7 -->
155+
156+
Each Dapr-enabled container app runs a sidecar process alongside your application. To call another Dapr-enabled app, make a local HTTP request to the Dapr sidecar, which handles service discovery and routing:
157+
158+
```
159+
http://localhost:3500/v1.0/invoke/<DAPR_APP_ID>/method/<METHOD_NAME>
160+
```
161+
162+
For example, to call the `catalog` method on an app with a Dapr App ID of `order-processor`:
163+
164+
```
165+
http://localhost:3500/v1.0/invoke/order-processor/method/catalog
166+
```
167+
168+
The sidecar resolves the target app through a dedicated DNS domain and routes the request through the Envoy proxy layer. This is the same infrastructure that handles FQDN-based routing. <!-- Source: Q9 -->
169+
170+
> [!NOTE]
171+
> Dapr uses its own DNS resolution path (the `.dapr` domain) separate from the standard FQDN resolution. Both paths route through the environment's proxy infrastructure. <!-- Source: Q9 -->
172+
173+
### Dapr App ID
174+
175+
<!-- Source: Q7, Q8 -->
176+
177+
The Dapr App ID is the identity other apps use to invoke your service. If you don't set an explicit App ID, the Dapr runtime defaults to your container app name. The ARM API shows `appId: null` when you don't configure a custom ID, but the runtime applies the app name automatically. Set a custom App ID in your Dapr configuration if you need a different identifier.
178+
179+
Dapr App IDs must be unique within an environment. If you try to deploy a container app with a Dapr App ID that's already in use by another app, the container app resource is created but its revision fails to provision (`provisioningState: Failed`). The error message identifies the conflicting App ID and the app that owns it. <!-- Source: Q8 -->
180+
181+
### Dapr-only apps (no HTTP ingress)
182+
183+
<!-- Source: Q21 -->
184+
185+
You can enable Dapr on a container app without configuring HTTP ingress. In this case, the app isn't reachable through an FQDN or app name, but other Dapr-enabled apps can still invoke it through Dapr service invocation. This pattern is useful for background workers or event processors that only need to receive calls from other services in the mesh. <!-- Source: Q21 -->
186+
187+
> [!TIP]
188+
> When you create a no-ingress app with the Azure CLI, omit both the `--ingress` and `--target-port` flags. Including `--target-port` without `--ingress` returns a usage error.
189+
190+
### Dapr sidecar configuration
191+
192+
<!-- Source: Q16 -->
193+
194+
You configure the Dapr sidecar through your container app's properties. Key settings include:
195+
196+
| Setting | Description |
197+
|---|---|
198+
| `appId` | The Dapr App ID (defaults to the container app name) |
199+
| `appPort` | The port your app listens on (falls back to the ingress target port) |
200+
| `appProtocol` | Protocol for Dapr-to-app communication (for example, `http`, `grpc`) |
201+
| `logLevel` | Dapr sidecar log verbosity |
202+
| `enableApiLogging` | Whether to log Dapr API calls |
203+
| `httpMaxRequestSize` | Maximum request body size in MB for Dapr's HTTP server |
204+
| `httpReadBufferSize` | Maximum size of the HTTP read buffer in KB |
205+
206+
For more information on configuring Dapr with Azure Container Apps, see [Dapr integration with Azure Container Apps](dapr-overview.md).
207+
208+
## Security for inter-app communication
209+
210+
<!-- Source: Q19 -->
211+
212+
Azure Container Apps includes several security features that affect how container apps communicate:
213+
214+
- **TLS by default**: All traffic between container apps routes through the Envoy proxy, which handles TLS termination. Set `allowInsecure` to `false` (the default) to enforce HTTPS redirects. <!-- Source: Q19 -->
215+
- **Client certificate mode (mTLS)**: Configure mutual TLS by setting the client certificate mode to `require`, `accept`, or `ignore`. <!-- Source: Q19 -->
216+
- **IP restrictions**: Define allow or deny rules to restrict which IP addresses can reach your app. <!-- Source: Q19 -->
217+
- **CORS policies**: Configure cross-origin resource sharing rules for browser-based clients calling your container apps. <!-- Source: Q19 -->
218+
219+
> [!NOTE]
220+
> When you use Dapr service invocation, the Dapr sidecars automatically secure communication with mutual TLS between services. You don't need to configure mTLS separately for Dapr-to-Dapr calls.
221+
222+
For more information, see [Ingress in Azure Container Apps](ingress-overview.md).
223+
224+
## Custom domains
225+
226+
<!-- Source: Q18 -->
227+
228+
You can map your own domain names to a container app by configuring custom domains on the ingress settings. Each custom domain can reference a managed or uploaded TLS certificate. <!-- Source: Q18 -->
229+
230+
Custom domains are registered alongside the default FQDN, so your app responds to both addresses. When other container apps in the environment need to reach your app, they can use either the default FQDN, the app name, or your custom domain.
231+
232+
For more information, see [Custom domains in Azure Container Apps](custom-domains-managed-certificates.md).
233+
234+
## Sample solution
235+
236+
A sample showing how to call between containers using both the FQDN and Dapr is available on [Azure Samples](https://github.com/Azure-Samples/container-apps-connect-multiple-apps).
237+
238+
## Related concepts
239+
240+
Understanding inter-app communication in Azure Container Apps connects to several related topics:
241+
242+
- [Environments in Azure Container Apps](environment.md): The shared boundary where container apps discover and communicate with each other
243+
- [Ingress in Azure Container Apps](ingress-overview.md): How to configure external and internal endpoints, TLS, and routing rules
244+
- [Dapr integration with Azure Container Apps](dapr-overview.md): Deeper coverage of Dapr components, pub/sub, and state management alongside service invocation
245+
- [Networking in Azure Container Apps](networking.md): VNet integration, private endpoints, and network security for your environment
246+
- [Revisions in Azure Container Apps](revisions.md) : How revision modes and traffic splitting affect inter-app routing
247+
248+
## Next step
55249

56250
> [!div class="nextstepaction"]
57-
> [Get started](get-started.md)
251+
> [Configure ingress for your container app](ingress-how-to.md)
252+

articles/container-apps/ingress-overview.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ The following apply to additional TCP ports:
101101

102102
- Only the main ingress port supports built-in HTTP features such as CORS and session affinity. When running HTTP on top of the extra TCP ports, these built-in features aren't supported.
103103

104-
- Port number `36985` is a reserved for internal health checks and isn't available to TCP applications or extra exposed ports on HTTP applications.
104+
- Port number `36985` is reserved for internal health checks and isn't available to TCP applications or extra exposed ports on HTTP applications.
105105

106106
For more information on how to enable extra ports, see [Configure ingress for your app](ingress-how-to.md#use-additional-tcp-ports).
107107

@@ -115,7 +115,7 @@ You can access your app in the following ways:
115115

116116
- The app name: You can use the app name for communication between apps in the same environment.
117117

118-
To get the FQDN for your app, see [Location](connect-apps.md#location).
118+
To get the FQDN for your app, see [Container app location (FQDN)](connect-apps.md#container-app-location-fqdn).
119119

120120
## IP restrictions
121121

0 commit comments

Comments
 (0)