Publishing a Go/Python app with a user-supplied Dockerfile silently drops the tool-invocation prefix
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 991
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 196
Description
## Summary
When a Go or Python app is published as a container, Aspire normally generates the Dockerfile and writes the tool-invocation prefix (`go run `, `python -m `, `python `) into the image `ENTRYPOINT`. If the app directory already contains a `Dockerfile`, Aspire skips generation and the image's entrypoint becomes entirely the user's responsibility — but nothing tells the user that, and nothing checks that the resulting image actually launches the program the resource describes.
## Details
`PublishAsDockerFile` replaces the executable resource with a container resource that shares its annotation collection, then appends `WithArgs(c => c.Args.Clear())`:
https://github.com/microsoft/aspire/blob/main/src/Aspire.Hosting/ExecutableResourceBuilderExtensions.cs#L124
So the executable's arguments — which describe a *local* invocation and often contain host paths — do not survive into the container. That is correct and intentional. The compute environment publishers (Docker Compose, Kubernetes, Azure Container Apps, Azure App Service) therefore see only the arguments added to the resource after containerization.
The generators bail out early when a `Dockerfile` already exists, for example:
- `src/Aspire.Hosting.Go/GoHostingExtensions.cs` — `PublishAsDockerFile(containerBuilder => { if (File.Exists(Path.Combine(appDirectory, "Dockerfile"))) { return; } ... })`
- `src/Aspire.Hosting.Python/PythonAppResourceBuilderExtensions.cs` — same shape
At that point nothing re-establishes the entrypoint. If the user's Dockerfile does not itself run the module/script/package the resource was declared with, the published image runs something else than the resource model says, with no error and no warning.
## Prior art in the repo
JavaScript already fails loudly in the analogous situation rather than publishing an image that ignores the configured run script:
https://github.com/microsoft/aspire/blob/main/src/Aspire.Hosting.JavaScript/JavaScriptHostingExtensions.cs#L1437
```
JavaScript app resource '{name}' is configured to run script '{script}', but publish is using the existing
Dockerfile '{path}'. An existing Dockerfile entrypoint cannot be changed automatically from runScriptName or
WithRunScript. Remove or rename the Dockerfile so Aspire can generate one, or call PublishAsDockerFile(...) and
set the container entrypoint explicitly.
```
## Why not just inject the prefix as the container command
Injecting `-m uvicorn` / `run ./cmd/api` as the container `command:` is not a general fix: Aspire does not know the user image's `ENTRYPOINT`, so the composed command line would be wrong for any base image that is not bare `python`/`go`.
## Suggested direction
Bring Go and Python in line with JavaScript — when an existing Dockerfile is used and the resource carries a non-default entrypoint that Aspire cannot express, either throw with actionable guidance or emit a publish-time warning, so the user knows the entrypoint is theirs to get right.
## Context
Found while reviewing #18999 (separating regular arguments from launch tool arguments). This behavior predates that PR — it is a consequence of `PublishAsDockerFile` clearing the executable's arguments — so it was split out rather than folded into that change. See https://github.com/microsoft/aspire/pull/18999#discussion_r3730620820.
Contributor guide
Research direction
Start with PublishAsDockerFile in src/Aspire.Hosting/ExecutableResourceBuilderExtensions.cs, then inspect the existing-Dockerfile paths in src/Aspire.Hosting.Go/GoHostingExtensions.cs and src/Aspire.Hosting.Python/PythonAppResourceBuilderExtensions.cs. Compare their behavior with the JavaScript handling in src/Aspire.Hosting.JavaScript/JavaScriptHostingExtensions.cs. Done means an existing Dockerfile with a non-default Go or Python entrypoint no longer publishes silently without actionable feedback.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, docker, go, python
- Domain
- devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100