Dockerfile Generator for .NET
Pick a project type and .NET version to generate a complete, correct multi-stage Dockerfile and .dockerignore, with inline comments explaining every stage.
How to use this tool
- Pick the project type — ASP.NET Core web, worker service, or console app.
- Pick the target .NET version and enter your project file name (with or without the
.csprojextension). - Leave multi-stage build on for a production-sized image, and turn on the non-root user toggle for anything internet-facing.
- Click Generate, then copy both the Dockerfile and the
.dockerignoreinto your project root.
What this tool generates
A complete, ready-to-build Dockerfile using Microsoft's official mcr.microsoft.com/dotnet/* container images — sdk for the build stage, aspnet for a web app's final stage, runtime for a worker or console app's final stage that doesn't need ASP.NET Core hosting. It's pure template generation from the options you pick; nothing is sent to an external API, no Docker daemon is involved, and no image is actually built or pulled.
Worked example
ASP.NET Core web, .NET 8, multi-stage on, non-root off, project file MyApp.csproj, port 8080 generates:
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyApp.csproj", "./"]
RUN dotnet restore "MyApp.csproj"
COPY . .
RUN dotnet publish "MyApp.csproj" -c Release -o /app/publish --no-restore
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app
ENV ASPNETCORE_HTTP_PORTS=8080
EXPOSE 8080
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]
Why the container listens on 8080, not 80
Starting with .NET 8, Microsoft's official ASP.NET Core container images default to port 8080 instead of 80, set via the ASPNETCORE_HTTP_PORTS environment variable. The change exists specifically so the container can run as a non-root user out of the box — Linux reserves ports below 1024 for the root user, so binding to port 80 directly would have forced every non-root container back onto root just to listen on the default HTTP port. This tool sets ASPNETCORE_HTTP_PORTS explicitly rather than relying on the image's own default, so the port is visible directly in the Dockerfile instead of being implicit.
Why multi-stage builds matter
The sdk image contains the full .NET SDK, MSBuild, and NuGet caches — everything needed to build the app, none of which is needed to run it. A multi-stage build compiles and publishes in a throwaway build stage using the sdk image, then copies only the published output into a fresh, much smaller aspnet or runtime image for the final stage. Turning the toggle off generates a single-stage Dockerfile instead — simpler to read, but the resulting image ships the entire SDK, which is both larger and a larger attack surface for a production container.
aspnet vs runtime: which base image for which project type
| Project type | Final-stage base image | Why |
|---|---|---|
| ASP.NET Core web | mcr.microsoft.com/dotnet/aspnet | Includes the ASP.NET Core shared runtime needed to host HTTP requests |
| Worker service | mcr.microsoft.com/dotnet/runtime | A BackgroundService/IHostedService worker doesn't host HTTP requests, so it only needs the base .NET runtime |
| Console app | mcr.microsoft.com/dotnet/runtime | Same reasoning — no ASP.NET Core hosting involved |
What this tool can't do
It doesn't run docker build, doesn't pull or validate that the referenced base images exist, and doesn't inspect your actual project file for its real dependencies (native libraries, additional exposed ports, extra COPY sources). Treat the output as a correct, working starting point for a typical project shape — review it against anything unusual in your own project before shipping it.
Choose your options and click Generate.