Fix persistent container endpoint allocation#17960
Conversation
Default persistent container endpoints to proxied unless proxy support is disabled, and remove delayed proxyless container endpoint allocation in favor of target-port public port defaults. Preserve endpoint and connection string event timing from release/13.3 and add coverage for the KeyVault emulator-style health check path.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17960Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17960" |
Set HTTP health check URIs during BeforeResourceStartedEvent again so surrogate resource builders that forward startup events continue to initialize their health checks. Add DCP coverage for the KeyVault-emulator-style surrogate pattern.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adjusts DCP endpoint allocation to make persistent container endpoints behave like normal container endpoints (proxied by default), removes the delayed proxyless allocation mechanism, and restores the proxyless targetPort-as-hostPort default. Also re-splits HTTP health check work so endpoint existence is validated on ResourceEndpointsAllocatedEvent, while the health check URI is bound on BeforeResourceStartedEvent for surrogate-forwarding scenarios.
Changes:
- Default persistent container endpoints to proxied unless explicitly proxyless / proxy support disabled; restore proxyless
targetPorthost-port defaulting. - Remove delayed/on-demand proxyless container port allocation plumbing and related test fake behavior.
- Move HTTP health check URI binding to
BeforeResourceStartedEvent, keeping endpoint existence validation duringResourceEndpointsAllocatedEvent.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Aspire.Hosting.Tests/DistributedApplicationTests.cs | Updates expectations for proxyless container port behavior (targetPort defaults host/public port). |
| tests/Aspire.Hosting.Tests/Dcp/TestKubernetesService.cs | Removes fake “late allocation” path; service port allocation now aligns with targetPort defaulting. |
| tests/Aspire.Hosting.Tests/Dcp/DcpExecutorTests.cs | Adds coverage for persistent container proxy defaults, targetPort defaulting behavior, and health check URI binding timing. |
| src/Aspire.Hosting/ResourceBuilderExtensions.cs | Moves HTTP health check URI binding to OnBeforeResourceStarted; keeps endpoint existence check during endpoint allocation. |
| src/Aspire.Hosting/Dcp/DcpResourceWatcher.cs | Stops publishing endpoints-allocated events on service updates; applies observed service address directly to endpoints. |
| src/Aspire.Hosting/Dcp/DcpModelUtilities.cs | Removes dynamic proxyless allocation helpers and simplifies service->endpoint application APIs. |
| src/Aspire.Hosting/Dcp/DcpExecutor.cs | Reorders/changes endpoint allocation publishing and defaults persistent container endpoints to proxied. |
| src/Aspire.Hosting/Dcp/ContainerCreator.cs | Builds proxyless container port mappings using resolved EndpointAnnotation.Port (targetPort defaulted). |
| src/Aspire.Hosting/ApplicationModel/OnDemandEndpointAllocationAnnotation.cs | Removes the on-demand endpoint allocation annotation type. |
| src/Aspire.Hosting/ApplicationModel/EndpointReference.cs | Removes endpoint allocation “on-demand” fallback; relies on allocated endpoint snapshots directly. |
| src/Aspire.Hosting/ApplicationModel/EndpointAnnotation.cs | Removes SpecifiedPort and relies on Port semantics (including proxyless targetPort default). |
Keep ResourceEndpointsAllocatedEvent dispatch aligned with release/13.4 so subscriber exceptions propagate and endpoint allocation callbacks complete before startup proceeds.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PR Testing ReportPR Information
CLI Version Verification
Changes AnalyzedHosting-only change to DCP endpoint allocation:
Change Categories
Test SetupA single file-based AppHost ( Test Scenarios ExecutedScenario 1: Proxyless container endpoint with only a target port (happy path)Config: Scenario 2: Persistent container defaults to proxied (happy path)Config: Scenario 3: HTTP health check on a container endpoint — KeyVault-emulator-style timing (happy path)Config: Scenario 4: Persistent container with explicit proxyless opt-out (boundary)Coverage Type: Boundary Persistence lifecycle verification (cross-cutting)After
|
| Scenario | Status | Notes |
|---|---|---|
| 1. Proxyless target-port default | ✅ Passed | host port == 8088, reachable |
| 2. Persistent defaults to proxied | ✅ Passed | random proxied port, persistent=true |
| 3. HTTP health check timing | ✅ Passed | Healthy |
| 4. Persistent + explicit proxyless | ✅ Passed | stays proxyless on 8090 |
| Persistence lifecycle (stop) | ✅ Passed | session removed, persistent survive |
Overall Result
✅ PR VERIFIED — All four scenarios plus the persistence lifecycle check behaved exactly as described in the PR. Proxyless container endpoints resolve to their target port immediately, persistent containers default to proxied while honoring an explicit proxyless opt-out, and container HTTP health checks bind and report Healthy.
Notes
- Tested on macOS arm64 with Docker Desktop using a file-based C# AppHost and the
traefik/whoamiimage. - This is an orchestration/timing change; behavior was validated against a real container runtime rather than only generated artifacts.
Use a fixed public Kafka port for the persistent reuse test and let the shared persistent-container helper disable DCP test port randomization when a test needs explicit ports to remain stable.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| "resource", | ||
| useTestContainerRegistry: true); | ||
| useTestContainerRegistry: true, | ||
| randomizePorts: false); |
There was a problem hiding this comment.
Kafka specifically requires the public port to be set in an environment variable, so forcing randomized ports changes the lifecycle key between runs.
|
❓ CLI E2E Tests unknown — 111 passed, 0 failed, 2 unknown (commit View all recordings
📹 Recordings uploaded automatically from CI run #27036216048 |
Persistent containers use proxied endpoints by default (same as session containers), while persistent executables and projects default to proxyless endpoints. Also document that proxyless container endpoints with only a targetPort immediately allocate the targetPort as the host port. Corrects docs that previously stated all persistent resources default to proxyless endpoints. Documents changes from microsoft/aspire#17960. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Pull request created: #1219
|
|
📝 Documentation has been drafted in microsoft/aspire.dev#1219 targeting Three documentation files updated to correct the persistent container endpoint proxy default, which was changed by this PR:
Note This draft PR needs human review before merging. |
* Fix persistent container endpoint proxy default docs Persistent containers use proxied endpoints by default (same as session containers), while persistent executables and projects default to proxyless endpoints. Also document that proxyless container endpoints with only a targetPort immediately allocate the targetPort as the host port. Corrects docs that previously stated all persistent resources default to proxyless endpoints. Documents changes from microsoft/aspire#17960. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: aspire-repo-bot[bot] <268009190+aspire-repo-bot[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: David Negstad <50252651+danegsta@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Fix persistent container endpoint proxy default docs Persistent containers use proxied endpoints by default (same as session containers), while persistent executables and projects default to proxyless endpoints. Also document that proxyless container endpoints with only a targetPort immediately allocate the targetPort as the host port. Corrects docs that previously stated all persistent resources default to proxyless endpoints. Documents changes from microsoft/aspire#17960. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: aspire-repo-bot[bot] <268009190+aspire-repo-bot[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: David Negstad <50252651+danegsta@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Description
Persistent container endpoints should behave like normal container endpoints unless the app explicitly opts out of proxy support. This keeps persistent containers compatible with integrations that depend on endpoint allocation happening before resource startup.
This change updates DCP endpoint allocation so persistent containers default to proxied endpoints unless
isProxied: falseorWithEndpointProxySupport(false)is applied. It also removes the delayed proxyless container allocation path and restores the previous target-port fallback: proxyless container endpoints with atargetPortand no public port immediately use the target port as the allocated host/public port.For HTTP health checks, this restores the 13.3 timing split: endpoint existence is still validated during
ResourceEndpointsAllocatedEvent, while the health-check URI is bound duringBeforeResourceStartedEvent. That matters for supported surrogate-resource integrations such as the KeyVault emulator, where the surrogate forwardsBeforeResourceStartedEventbut notResourceEndpointsAllocatedEvent.The endpoint allocation event is intentionally kept on the 13.4
BlockingSequentialdispatch behavior, rather than matching 13.3'sNonBlockingConcurrentdispatch. That preserves 13.4 exception propagation and ensures allocation subscribers complete before startup continues.User-facing behavior
Proxyless container endpoints now resolve immediately when only a target port is specified:
That endpoint allocates public/host port
6379instead of waiting for a delayed allocation update. Persistent executables keep their existing default proxyless behavior.Breaking changes
This changes endpoint allocation timing and default endpoint behavior for container scenarios. Users who depended on delayed runtime allocation for proxyless container endpoints without an explicit public port should specify the desired public port explicitly or rely on the restored target-port default.
Validation included the DCP executor test suite and a real KeyVault emulator smoke test for both session and persistent container lifetimes.
Checklist
<remarks />and<code />elements on your triple slash comments?