Skip to content

[docs] Add portable volume path environment variables - #1593

Merged
David Pine (IEvangelist) merged 2 commits into
release/13.6from
docs/pr-19404-33354366513-1-481b17481bfc0a9f
Sep 1, 2026
Merged

[docs] Add portable volume path environment variables#1593
David Pine (IEvangelist) merged 2 commits into
release/13.6from
docs/pr-19404-33354366513-1-481b17481bfc0a9f

Conversation

@aspire-repo-bot

Copy link
Copy Markdown
Contributor

Documents changes from microsoft/aspire#19404

@mitchdenny

Targeting release/13.6 based on the source PR milestone 13.6.

Why

microsoft/aspire#19404 adds an env parameter to WithVolume (and to Kubernetes WithPersistentVolume) so a project or executable can read one environment variable for its storage path in both local run mode and published/deployed modes:

  • In run mode, projects and executables get a deterministic, workload-scoped directory under the AppHost's IAspireStore.
  • In publish/deploy modes (Docker Compose, Kubernetes, Azure Container Apps), the variable resolves to the configured container mount path.
  • The Kubernetes WithPersistentVolume(..., env: ...) overload composes the same behavior for first-class persistent volumes.

This is new public API (new_public_type, integration_readme_changed signals both fired) with a "User-facing usage" section in the PR body, so it needed a docs update.

What changed

  • src/frontend/src/content/docs/fundamentals/persist-data-volumes.mdx: added a new "Use a portable volume path environment variable" section describing the env parameter on WithVolume, its run-mode vs. publish-mode behavior, and a note that it's only available for projects/executables (containers always get target).
  • src/frontend/src/content/docs/deployment/kubernetes/persistent-volumes.mdx: added a new "Bind with a portable path environment variable" subsection under "Bind a volume to a workload", describing the WithPersistentVolume(volume, mountPath, env: ...) overload, local-container-volume naming behavior, and the one-volume-per-execution-type limitation.

Both pages are existing pages that already covered WithVolume / WithPersistentVolume; no new pages were created.

Generated by PR Documentation Check for #19404 · auto · 131.3 AIC · ⌖ 7.18 AIC · ⊞ 19.6K ·

Documents changes from microsoft/aspire#19404

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aspire-repo-bot aspire-repo-bot Bot added the docs-from-code Copilot initiated issue from dotnet/aspire repo label Aug 31, 2026
@aspire-repo-bot

Copy link
Copy Markdown
Contributor Author

Frontend HTML artifact ready

The latest frontend build uploaded the frontend-dist artifact for PR #1593. Use the VS Code button below to open this PR with GitHub Artifacts Explorer and browse the built HTML locally.

VS Code: Open PR #1593 artifacts

This comment updates automatically when a new frontend build artifact is uploaded.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Documents new Aspire hosting APIs that let workloads consume a single environment variable representing the “effective” volume path across run mode (local execution) and publish/deploy modes (Compose/Kubernetes/ACA). This updates existing volume and Kubernetes persistent-volume guidance to reflect the new env parameter behavior introduced in microsoft/aspire#19404.

Changes:

  • Adds a new fundamentals section describing WithVolume(..., env: ...) and its portable path behavior (C# + TypeScript).
  • Adds a Kubernetes subsection documenting WithPersistentVolume(..., env: ...) / withKubernetesPersistentVolumeMount(..., { env }), including local container naming behavior and limitations.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/frontend/src/content/docs/fundamentals/persist-data-volumes.mdx Adds guidance for portable volume path env vars via WithVolume(..., env: ...), with a cross-link to Kubernetes PV details.
src/frontend/src/content/docs/deployment/kubernetes/persistent-volumes.mdx Adds Kubernetes PV binding guidance for portable path env vars via env, plus notes on local container behavior and limitations.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/frontend/src/content/docs/deployment/kubernetes/persistent-volumes.mdx Outdated

@IEvangelist David Pine (IEvangelist) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated docs-accuracy review

Source of truth: microsoft/aspire @ main (HEAD 1cdf7d17248ae78ee018abbc314f772ace5e624d).

⚠️ Branch note (non-blocking): This PR targets release/13.6, which does not exist in microsoft/aspire. The portable volume-path env feature ships via microsoft/aspire#19404 (merge 54c1f929ae), which is present on main but not yet in a GA release (latest tag is v13.5.3; there is no v13.6 tag). I therefore verified every claim against upstream/main. If a release/13.6 branch is later cut, these claims should be re-confirmed against it.

Phase A — claims: 14 non-narrative claims extracted → ✅ 14 verified, 0 verified-with-nuance, 0 unverifiable, 0 contradicted.
Phase B — doc-tester: 2 routes exercised (/fundamentals/persist-data-volumes/, /deployment/kubernetes/persistent-volumes/) → 0 critical, 0 warnings; 1 knowledge gap (local build predates PR — mitigated).

This is a high-fidelity PR: the prose tracks the product README (src/Aspire.Hosting.Kubernetes/README.md) almost verbatim, and both the C# and TypeScript examples use the correct per-language parameter order.


Phase A — Claim verification

No contradicted or unverifiable claims, so there are no inline blocking comments. All evidence is below for audit.

✅ 14 verified claims (click to expand)

Fundamentals — fundamentals/persist-data-volumes.mdx

id claim evidence (microsoft/aspire @ main)
F1 WithVolume gains an optional env parameter src/Aspire.Hosting/VolumeResourceBuilderExtensions.cs:39WithVolume<T>(builder, string name, string target, string env, bool isReadOnly = false) where T : IComputeResource, IResourceWithEnvironment
F2 C# WithVolume("data", "/data", env: "DATA_PATH") on a project (order: name, target, env) same signature; a project satisfies IComputeResource, IResourceWithEnvironment
F3 TS withVolume("/data", "data", "DATA_PATH") on a project (order: target, name, env) generated TS API tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts — project promise exposes withVolume(target, name, env, options?)
F4 Run mode → project/executable gets a deterministic workload-scoped dir under the AppHost local store as DATA_PATH VolumeResourceBuilderExtensions.cs remarks: "Projects and executables receive a workload-scoped IAspireStore directory in run mode"
F5 Containers, and any workload in publish/deploy, receive /data (the target) same remarks: "Containers receive target in run and publish modes"; publish = target
F6 env only on projects/executables; container equivalent is .WithEnvironment("DATA_PATH", "/data") C# container WithVolume overloads have no env (ContainerResourceBuilderExtensions.cs:228,265); polyglot container export remark in Ats/CoreExports.cs: container is "exactly equivalent to withVolume(target, name).withEnvironment(env, target)"
F7 Cross-link to …/persistent-volumes/#bind-with-a-portable-path-environment-variable K page (this PR) adds H3 "Bind with a portable path environment variable" → slug matches; self-consistent

Kubernetes — deployment/kubernetes/persistent-volumes.mdx

id claim evidence (microsoft/aspire @ main)
K1 C# AddPersistentVolume("data").WithCapacity("20Gi") + .WithPersistentVolume(data, "/data", env: "DATA_PATH") src/Aspire.Hosting.Kubernetes/KubernetesPersistentVolumeExtensions.csAddPersistentVolume(builder, [ResourceName] string name) L46; WithCapacity(builder, string capacity) L119; WithPersistentVolume<T>(builder, volume, string mountPath, string env, bool isReadOnly = false) where T : IComputeResource, IResourceWithEnvironment L364 (doc-comment example uses env: "DATA_PATH")
K2 TS addPersistentVolume / withCapacity / withKubernetesPersistentVolumeMount(data, '/data', { env: 'DATA_PATH' }) [AspireExport] on AddPersistentVolume & WithCapacity; [AspireExport("withKubernetesPersistentVolumeMount")] on WithPersistentVolumeMountForExport<T>(builder, volume, mountPath, bool isReadOnly = false, string? env = null) → trailing optionals become an options bag { env }; env-carrying C# overload is [AspireExportIgnore(Reason = "Polyglot AppHosts use the withKubernetesPersistentVolumeMount adapter.")]
K3 Run mode → DATA_PATH is a persistent dir in the local store, normally under the intermediate-output dir (cleaning build outputs can remove it) KubernetesPersistentVolumeLocalStorage.cs:27-28 "IAspireStore is scoped to the AppHost's intermediate output directory…"; README.md:83
K4 Publish/deploy → DATA_PATH contains the mount path /data README.md:85 "When published or deployed, DATA_PATH contains /data"
K5 Local containers use a worktree-scoped container volume when the mount names an env var; mounts without one keep the PV's own name README.md:83; KubernetesPersistentVolumeExtensions.cs:467 "Computes the worktree-scoped local volume name for a run-mode container binding"
K6 A single PV can't be shared between local containers and local projects/executables KubernetesEnvironmentExtensions.cs:191 throws: "Run mode cannot provide one shared backing store across those execution types. Use only containers or only projects/executables for this volume." + README.md:83
K7 isReadOnly is enforced after deployment, but Aspire can't make a directory read-only for a host process README.md:85 verbatim; run-mode resolver returns a writable GetOrCreatePath dir; isReadOnly flows only to the pod volume source (Extensions/ResourceExtensions.cs:245)

Note (not a defect): C# uses (name, target) = ("data","/data") while TS reorders to (target, name) = ("/data","data"). Both are correct per their respective generated signatures — the polyglot TS surface is target-first by design.


Phase B — Doc-tester results

Playwright-only run against the local docs frontend; no microsoft/aspire source was consulted in this phase.

Routes exercised: /fundamentals/persist-data-volumes/, /deployment/kubernetes/persistent-volumes/

Category Passed Failed Warnings
Page health (HTTP/console) 2 0 0
Reused component rendering 2 0 0
Insertion-region integrity 2 0 0
Links 1 0 0

Critical issues: none.
Warnings: none (from a blind-user perspective).

Passed checks

  • /fundamentals/persist-data-volumes/ — HTTP 200; 0 console errors (3 benign Vite dev-server No popup container found warnings, content-independent). Renders multiple Tabs syncKey="aspire-lang" (C#/TypeScript) + title="AppHost.cs" code figures.
  • /deployment/kubernetes/persistent-volumes/ — HTTP 200; 0 console errors, 0 warnings. Renders 6 TypeScript tabs, the pre-existing withKubernetesPersistentVolumeMount example, and the existing AddPersistentVolume(...).WithCapacity(...) example.
  • Insertion regions intact: the Kubernetes Aside type="caution" "Workloads are promoted to StatefulSet" (the node the new H3 is inserted before) renders as a landmark; the Fundamentals "Use bind mounts" H2 (the node the new H2 is inserted before) renders. The PR introduces no new component types — only new instances of already-rendering components.
  • Link (F7): the new internal link targets a page that returns HTTP 200; the anchor heading is added by this same PR.

Knowledge gap — local docs build predates this PR: Neither new heading ("Use a portable volume path environment variable" / "Bind with a portable path environment variable") nor the string DATA_PATH is present in the served HTML, so I could not exercise the new prose/examples directly as a blind user. Mitigation: validated page health, confirmed every reused component already renders on both target pages, confirmed both insertion anchors are intact, and confirmed the one new link points to an existing page. This is a test-environment limitation, not a documentation defect.


Verdict: APPROVE

Every non-narrative claim (14/14) is verified against microsoft/aspire @ main, both the C# and TypeScript examples use the correct per-language signatures, and the doc-tester run found no critical issues or warnings. The only caveat is the informational branch-name mismatch (release/13.6 not present in microsoft/aspire); re-confirm against that branch if/when it is cut.

🤖 Automated Phase A (source-of-truth claims) + Phase B (doc-tester) review. Phase A read microsoft/aspire @ main; Phase B used Playwright against the local docs site only.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@IEvangelist
David Pine (IEvangelist) merged commit be0e603 into release/13.6 Sep 1, 2026
10 checks passed
@IEvangelist
David Pine (IEvangelist) deleted the docs/pr-19404-33354366513-1-481b17481bfc0a9f branch September 1, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs-from-code Copilot initiated issue from dotnet/aspire repo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants