Skip to content

[docs] Document run script and Dockerfile conflict for AddJavaScriptApp#1014

Open
aspire-repo-bot[bot] wants to merge 1 commit into
release/13.4from
docs/js-app-dockerfile-run-script-conflict-main-a564a10b89bc10ba
Open

[docs] Document run script and Dockerfile conflict for AddJavaScriptApp#1014
aspire-repo-bot[bot] wants to merge 1 commit into
release/13.4from
docs/js-app-dockerfile-run-script-conflict-main-a564a10b89bc10ba

Conversation

@aspire-repo-bot
Copy link
Copy Markdown
Contributor

Documents changes from microsoft/aspire#16969

Authored by @sebastienros.

Targeting release/13.4 based on the source PR milestone 13.4 (exact match).

Why this PR is needed

Aspire 13.4 introduces publish-time validation that fails fast when AddJavaScriptApp is configured with an explicit runScriptName or .WithRunScript(...) but the app directory already contains a user-authored Dockerfile. Previously, Aspire would silently ignore the requested run script and use the Dockerfile ENTRYPOINT instead. Now it throws a DistributedApplicationException with a clear error message and guidance on how to fix the conflict.

This is a user-visible behavior change that requires documentation so developers understand why they get the error and what their resolution options are.

What was added

A new subsection "Run script and existing Dockerfile conflict" under the "What JavaScript app resources mean in production" section in deployment/javascript-apps.mdx. The subsection:

  • Explains when the conflict occurs.
  • Shows the exact error message Aspire throws.
  • Documents the two resolution paths:
    1. Remove or rename the Dockerfile so Aspire can generate one.
    2. Call PublishAsDockerFile(...) and set the container entrypoint explicitly (with C# and TypeScript examples).
  • Notes that using the implicit default runScriptName ("dev") without custom arguments is always allowed.

A new bullet was also added to the "Common mistakes" section.

Files modified

  • src/frontend/src/content/docs/deployment/javascript-apps.mdx — updated (new subsection + new common-mistakes bullet)

Generated by PR Documentation Check for issue #16969 · ● 64.4M ·

When AddJavaScriptApp is configured with an explicit runScriptName or
WithRunScript and an existing user-authored Dockerfile is present,
Aspire now fails at publish time with a clear error instead of silently
ignoring the requested run script.

Document the conflict, the error message, and the two resolution paths:
remove/rename the Dockerfile, or use PublishAsDockerFile with an
explicit container entrypoint.

Documents changes from microsoft/aspire#16969.

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 May 19, 2026
@aspire-repo-bot aspire-repo-bot Bot requested a review from mitchdenny May 19, 2026 18:02
@IEvangelist IEvangelist marked this pull request as ready for review May 20, 2026 02:16
@IEvangelist IEvangelist self-requested a review as a code owner May 20, 2026 02:16
Copilot AI review requested due to automatic review settings May 20, 2026 02:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Documents a new Aspire 13.4 publish-time validation behavior for AddJavaScriptApp when a user-authored Dockerfile is present and a run script override is configured, explaining the resulting error and how to resolve it.

Changes:

  • Added a “Run script and existing Dockerfile conflict” subsection describing when the validation triggers, including the error text and resolution options.
  • Added a related bullet to the “Common mistakes” section.
Comments suppressed due to low confidence (1)

src/frontend/src/content/docs/deployment/javascript-apps.mdx:1277

  • This “Common mistakes” bullet says any explicit runScriptName/.WithRunScript(...) with an existing user Dockerfile causes the conflict, but the section above notes that the default runScriptName ("dev") without custom args is allowed. Consider tightening the bullet to match the actual conflict condition (non-default script name and/or custom args).
- Passing an explicit `runScriptName` or calling `.WithRunScript(...)` when the app directory already has a user-authored Dockerfile, which causes a publish-time conflict error. Remove the Dockerfile or use `PublishAsDockerFile(...)` with an explicit container entrypoint to resolve the conflict.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


### Run script and existing Dockerfile conflict

When `AddJavaScriptApp` finds an existing user-authored `Dockerfile` in the app directory, Aspire uses that Dockerfile as the publish container image and cannot safely replace its `ENTRYPOINT`. If you also pass an explicit `runScriptName` to `AddJavaScriptApp` or call `.WithRunScript(...)` with a non-default script name, Aspire fails at publish time with a clear error rather than silently emitting an image that ignores the requested script:
Comment on lines +1240 to +1244
```csharp title="AppHost.cs"
builder
.AddJavaScriptApp("js", "./js", runScriptName: "migrate")
.WithBun()
.PublishAsDockerFile(container => container
Copy link
Copy Markdown
Member

@IEvangelist IEvangelist left a comment

Choose a reason for hiding this comment

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

Summary

Review generated by running the doc-tester skill against the changed page in this PR.

I checked out pr-1014, started the docs site locally with aspire start --isolated against the AppHost in this worktree, and read the rendered page at /deployment/javascript-apps/#run-script-and-existing-dockerfile-conflict in Playwright as a new user would. I followed the skill's user‑centric methodology: only the documentation site was consulted to validate behavior; nothing was inferred from Aspire source.

Net assessment: the new subsection lands cleanly. The added narrative, error block, two‑option resolution, code samples on both tabs, and the new bullet under "Common mistakes" all render correctly, are internally consistent, and use API surface that matches established patterns elsewhere on the same page. Two minor nits and one knowledge gap below — none of them block.

Verdict: Approve.

What I verified

Check Result
Page renders at /deployment/javascript-apps/
New anchor #run-script-and-existing-dockerfile-conflict resolves and is reachable from the in-page "On this page" nav and from the section breadcrumb
Section heading level (H3 under the H2 "What JavaScript app resources mean in production") matches its sibling "Build-only container validation"
C# code sample renders with correct syntax highlighting in the C# tab
TypeScript code sample renders with correct syntax highlighting in the TypeScript tab; switching tabs updates ?aspire-lang=typescript via the shared syncKey='aspire-lang'
Quoted error message in the text code block renders verbatim and matches what the PR body says Aspire throws
New "Common mistakes" bullet renders alongside the existing list with consistent formatting and terminology (runScriptName, .WithRunScript(...), PublishAsDockerFile(...))
AddJavaScriptApp("js", "./js", runScriptName: "migrate") — same 3‑arg runScriptName: overload pattern that the rest of deployment/javascript-apps.mdx already uses (e.g. AddViteApp("react", "./frameworks/react", runScriptName: "dev"), AddNextJsApp("nextjs", "./frameworks/nextjs", runScriptName: "dev"))
WithBun() / withBun() matches usage in integrations/frameworks/javascript.mdx and integrations/frameworks/bun-apps.mdx
WithEntrypoint("bun") matches the .WithEntrypoint("/bin/sh") pattern shown in architecture/resource-api-patterns.mdx and architecture/resource-examples.mdx
No internal links were added by this change; nothing to validate for trailing‑slash / target‑exists
Editorial polish (grammar, spelling, capitalization, "Dockerfile" vs "dockerfile" consistency)

Findings

Nit — TS publishAsDockerFile callback signature is new shape for this doc

Severity: nit (advisory)
Location: src/frontend/src/content/docs/deployment/javascript-apps.mdx, lines 1252‑1260

The new TS snippet uses a configure‑style callback that receives a container builder:

.publishAsDockerFile(async container => {
  container.withEntrypoint('bun');
  container.withArgs(['src/migrate.ts']);
});

Every other TypeScript publishAsDockerFile call elsewhere in this same page (lines 617, 674) — and the only other one on the site at app-host/executable-resources.mdx (lines 298, 337) — uses the no‑argument form:

.publishAsDockerFile(async () => {});

So the callback‑with‑container shape is correct (it mirrors the C# overload right above it), but this is the first place in the docs that demonstrates it for TS. A reader who has only seen the no‑arg form may briefly wonder whether the parameter is real. A one‑line lead‑in such as "the callback receives the container builder so you can configure it directly" would smooth this over, or alternatively normalize the existing publishAsDockerFile(async () => {}) examples in this file to also show the parameter when relevant. Not blocking.

Nit — Both samples start mid‑pipeline

Severity: nit (advisory)
Location: lines 1240‑1247 (C#) and 1252‑1260 (TS)

Both code blocks begin with builder.… / await builder.… without showing the surrounding var builder = DistributedApplication.CreateBuilder(args); / const builder = await createBuilder(); and the closing builder.Build().Run(); / await builder.build().run();. The immediately preceding "Build-only container validation" example (lines 1188‑1215) shows the full builder bootstrap; the new snippets are shorter. This is consistent with several earlier inline examples in the same file (e.g. line 593‑596) so I'm flagging it as advisory only — the truncated form helps the snippet focus on the conflict resolution, which is the right tradeoff.

Knowledge gap — TS API surface for publishAsDockerFile is not documented on the site

What I needed to know: Does the TS publishAsDockerFile accept an async (container) => … callback whose argument exposes withEntrypoint and withArgs?
Source of my knowledge: I confirmed the C# PublishAsDockerFile(container => container.WithEntrypoint(…).WithArgs(…)) shape against architecture/resource-api-patterns.mdx and architecture/resource-examples.mdx. For TS, I could not find a published API reference on the docs site under /reference/ or anywhere else that pins the callback signature. As a new user following only the docs, I would have to trust the example.
User impact: TS users won't be able to verify the callback contract against a reference. They'll likely succeed by copy‑paste, but they can't discover that, say, container.withImage(...) or container.withBuildArg(...) are also reachable from the same callback.
Recommendation: Reasonable to assume for this PR; opening or referencing a TS API reference page for publishAsDockerFile would be a follow‑up doc task and is out of scope here.

Suggested wording (optional)

A small clarification could be added inline above the TS tab without rewriting the diff:

The publishAsDockerFile callback receives the container resource builder, which you can configure with methods like WithEntrypoint(...) / withEntrypoint(...) and WithArgs(...) / withArgs(...).

This would also pre‑answer the "what else can I call on container?" question for both C# and TS readers.

Things explicitly tested

  • Navigated to http://localhost:62292/deployment/javascript-apps/ (local frontend resource URL discovered via aspire resources --format Json).
  • Confirmed document.querySelector('#run-script-and-existing-dockerfile-conflict') resolves to an H3 with text "Run script and existing Dockerfile conflict".
  • Read the rendered error code block — it matches the PR's quoted text character‑for‑character.
  • Switched between the C# and TypeScript tabs on the new section. The shared syncKey='aspire-lang' propagates across the whole page as expected.
  • Confirmed the new entry appears in the page's "On this page" sidebar navigation as Run script and existing Dockerfile conflict.
  • Confirmed the new "Common mistakes" bullet renders inside the existing <ul> without breaking formatting.

Out of scope / not tested

  • I did not actually trigger the runtime conflict against a live AddJavaScriptApp + Dockerfile repo, because that would require an Aspire CLI build that includes the change from microsoft/aspire#16969 (the source change this PR documents). The PR body says the behavior is new in 13.4, and release/13.4 is the base branch, so the documented behavior matches the targeted release.
  • I did not run the docs build/lint locally — CI on the PR is already green.

Generated by the doc‑tester skill in a local worktree of microsoft/aspire.dev, against the rendered docs site started with aspire start --isolated.

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