dotnet-dockerfile
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese.NET Dockerfile Generator
.NET Dockerfile 生成器
Generate production-ready multi-stage Dockerfiles for .NET applications.
为.NET应用生成可用于生产环境的多阶段Dockerfile。
Workflow
工作流程
- Determine .NET version (8, 9, or 10) from project file or ask user
- Identify project type: ASP.NET Core web app, API, worker service, or console app
- Locate project file path (e.g., )
src/MyApp/MyApp.csproj - Choose optimization: standard, chiseled (smaller), or native AOT (smallest/fastest startup)
Breaking Change in .NET 10: Ubuntu is now the default Linux distribution for all .NET container images. Debian images are no longer provided. Tags like,10.0, and10.0-nobleall use Ubuntu 24.04 "Noble Numbat".10.0-noble-chiseled
- 从项目文件中确定.NET版本(8、9或10),或询问用户
- 识别项目类型:ASP.NET Core Web应用、API、工作服务或控制台应用
- 定位项目文件路径(例如:)
src/MyApp/MyApp.csproj - 选择优化方式:标准、精简(更小体积)或Native AOT(体积最小/启动最快)
.NET 10中的重大变更:Ubuntu现在是所有.NET容器镜像的默认Linux发行版,不再提供Debian镜像。、10.0和10.0-noble等标签均使用Ubuntu 24.04 "Noble Numbat"。10.0-noble-chiseled
Image Selection Guide
镜像选择指南
| Scenario | Runtime Image | Compressed Size |
|---|---|---|
| Standard ASP.NET | | ~92 MB |
| Smaller footprint | | ~52 MB |
| Production (recommended) | | ~53 MB |
| Azure Linux distroless | | ~55 MB |
| Self-contained | | ~22 MB |
| Native AOT | | ~12 MB |
Chiseled images: Ubuntu-based, no shell, no package manager, non-root by default. Recommended for production.
Azure Linux distroless: Alternative to chiseled with Microsoft supply chain security. Similar benefits: no shell, non-root by default.
| 场景 | 运行时镜像 | 压缩后体积 |
|---|---|---|
| 标准ASP.NET应用 | | ~92 MB |
| 更小占用空间 | | ~52 MB |
| 生产环境(推荐) | | ~53 MB |
| Azure Linux无发行版镜像 | | ~55 MB |
| 自包含部署 | | ~22 MB |
| Native AOT | | ~12 MB |
精简镜像(Chiseled images):基于Ubuntu,无Shell、无包管理器,默认以非root用户运行,推荐用于生产环境。
Azure Linux无发行版镜像:精简镜像的替代方案,具备微软供应链安全能力,同样拥有无Shell、默认非root运行等优势。
Standard Pattern
标准模式
dockerfile
undefineddockerfile
undefinedsyntax=docker/dockerfile:1
syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
Copy project files and restore (cache layer)
复制项目文件并还原依赖(缓存层)
COPY *.csproj ./
RUN dotnet restore
COPY *.csproj ./
RUN dotnet restore
Copy source and publish
复制源代码并发布
COPY . .
RUN dotnet publish -c Release -o /app/publish
COPY . .
RUN dotnet publish -c Release -o /app/publish
Runtime
运行时阶段
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled AS production
WORKDIR /app
COPY --from=build /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApp.dll"]
undefinedFROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled AS production
WORKDIR /app
COPY --from=build /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApp.dll"]
undefinedMulti-Project Solution Pattern
多项目解决方案模式
For solutions with multiple projects, copy all .csproj files first:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src针对包含多个项目的解决方案,先复制所有.csproj文件:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /srcCopy solution and project files (cache layer)
复制解决方案和项目文件(缓存层)
COPY .sln ./
COPY src/MyApp/.csproj ./src/MyApp/
COPY src/MyApp.Core/.csproj ./src/MyApp.Core/
COPY tests/MyApp.Tests/.csproj ./tests/MyApp.Tests/
RUN dotnet restore
COPY .sln ./
COPY src/MyApp/.csproj ./src/MyApp/
COPY src/MyApp.Core/.csproj ./src/MyApp.Core/
COPY tests/MyApp.Tests/.csproj ./tests/MyApp.Tests/
RUN dotnet restore
Copy everything and publish
复制所有文件并发布
COPY . .
RUN dotnet publish src/MyApp -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled AS production
WORKDIR /app
COPY --from=build /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApp.dll"]
undefinedCOPY . .
RUN dotnet publish src/MyApp -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled AS production
WORKDIR /app
COPY --from=build /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApp.dll"]
undefinedSelf-Contained Deployment
自包含部署
Bundles .NET runtime with app, enables smallest runtime-deps images:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish \
--self-contained true \
-r linux-x64
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-noble-chiseled AS production
WORKDIR /app
COPY /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["./MyApp"]将.NET运行时与应用捆绑,可使用体积最小的runtime-deps镜像:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish \
--self-contained true \
-r linux-x64
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-noble-chiseled AS production
WORKDIR /app
COPY /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["./MyApp"]Native AOT (Fastest Startup)
Native AOT(最快启动速度)
Compiles to native code. Smallest image (~12 MB), fastest startup:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0-aot AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-noble-chiseled AS production
WORKDIR /app
COPY /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["./MyApp"]Dedicated AOT SDK images include native compilation prerequisites:
- (Ubuntu, also tagged
mcr.microsoft.com/dotnet/sdk:10.0-aot)10.0-noble-aot mcr.microsoft.com/dotnet/sdk:10.0-alpine-aotmcr.microsoft.com/dotnet/sdk:10.0-azurelinux3.0-aot
Requires in .csproj:
xml
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>Limitations: No runtime reflection, not all libraries compatible.
编译为原生代码,镜像体积最小(约12 MB),启动速度最快:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0-aot AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-noble-chiseled AS production
WORKDIR /app
COPY /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["./MyApp"]专用AOT SDK镜像包含原生编译所需的依赖项:
- (Ubuntu,也标记为
mcr.microsoft.com/dotnet/sdk:10.0-aot)10.0-noble-aot mcr.microsoft.com/dotnet/sdk:10.0-alpine-aotmcr.microsoft.com/dotnet/sdk:10.0-azurelinux3.0-aot
项目文件中需添加:
xml
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>限制:不支持运行时反射,并非所有库都兼容。
Dockerfile-less Container Publishing
无Dockerfile的容器发布
.NET 10 supports publishing containers directly from the SDK—no Dockerfile required:
bash
undefined.NET 10支持直接从SDK发布容器,无需Dockerfile:
bash
undefinedPublish to local container runtime
发布到本地容器运行时
dotnet publish --os linux --arch x64 /t:PublishContainer
dotnet publish --os linux --arch x64 /t:PublishContainer
Publish directly to a registry (no Docker needed)
直接发布到镜像仓库(无需Docker)
dotnet publish --os linux --arch x64 /t:PublishContainer
-p ContainerRegistry=ghcr.io
-p ContainerRepository=myorg/myapp
-p ContainerRegistry=ghcr.io
-p ContainerRepository=myorg/myapp
dotnet publish --os linux --arch x64 /t:PublishContainer
-p ContainerRegistry=ghcr.io
-p ContainerRepository=myorg/myapp
-p ContainerRegistry=ghcr.io
-p ContainerRepository=myorg/myapp
Multi-architecture publishing
多架构发布
dotnet publish /t:PublishContainer
-p ContainerRuntimeIdentifiers="linux-x64;linux-arm64"
-p ContainerRuntimeIdentifiers="linux-x64;linux-arm64"
**Project file configuration:**
```xml
<PropertyGroup>
<!-- Control image format: Docker or OCI -->
<ContainerImageFormat>OCI</ContainerImageFormat>
<!-- Customize base image -->
<ContainerBaseImage>mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled</ContainerBaseImage>
<!-- Set image name and tag -->
<ContainerRepository>myapp</ContainerRepository>
<ContainerImageTag>1.0.0</ContainerImageTag>
</PropertyGroup>dotnet publish /t:PublishContainer
-p ContainerRuntimeIdentifiers="linux-x64;linux-arm64"
-p ContainerRuntimeIdentifiers="linux-x64;linux-arm64"
**项目文件配置**:
```xml
<PropertyGroup>
<!-- 控制镜像格式:Docker或OCI -->
<ContainerImageFormat>OCI</ContainerImageFormat>
<!-- 自定义基础镜像 -->
<ContainerBaseImage>mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled</ContainerBaseImage>
<!-- 设置镜像名称和标签 -->
<ContainerRepository>myapp</ContainerRepository>
<ContainerImageTag>1.0.0</ContainerImageTag>
</PropertyGroup>Development Stage
开发阶段
Add a development stage for local dev with hot reload:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS base
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
FROM base AS development
COPY . .
ENTRYPOINT ["dotnet", "watch", "run"]
FROM base AS build
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled AS production
WORKDIR /app
COPY /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApp.dll"]Build development:
docker build --target development -t myapp:dev .添加开发阶段,支持本地开发热重载:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS base
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
FROM base AS development
COPY . .
ENTRYPOINT ["dotnet", "watch", "run"]
FROM base AS build
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled AS production
WORKDIR /app
COPY /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApp.dll"]构建开发镜像:
docker build --target development -t myapp:dev .Cache Optimization
缓存优化
Use BuildKit cache mount for NuGet packages:
dockerfile
RUN \
dotnet restore使用BuildKit缓存挂载来缓存NuGet包:
dockerfile
RUN \
dotnet restoreSHA Pinning for Production
生产环境的SHA固定
Pin exact image digests for reproducibility and security:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0@sha256:abc123... AS buildTo find the current digest, run:
bash
docker pull mcr.microsoft.com/dotnet/sdk:10.0
docker inspect --format='{{index .RepoDigests 0}}' mcr.microsoft.com/dotnet/sdk:10.0固定镜像的精确摘要,确保可复现性和安全性:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0@sha256:abc123... AS build如需获取当前摘要,运行以下命令:
bash
docker pull mcr.microsoft.com/dotnet/sdk:10.0
docker inspect --format='{{index .RepoDigests 0}}' mcr.microsoft.com/dotnet/sdk:10.0Required .dockerignore
必备的.dockerignore
Always create :
.dockerignoredockerignore
**/bin/
**/obj/
**/.vs/
**/.vscode/
**/node_modules/
**/*.user
**/*.userosscache
**/*.suo
*.md
.git
.gitignore
Dockerfile*
docker-compose*务必创建文件:
.dockerignoredockerignore
**/bin/
**/obj/
**/.vs/
**/.vscode/
**/node_modules/
**/*.user
**/*.userosscache
**/*.suo
*.md
.git
.gitignore
Dockerfile*
docker-compose*Verification Checklist
验证检查清单
- SDK image for build stage, runtime/aspnet for production
- .NET 8+ uses port 8080 (not 80)
- Copy .csproj files before source for cache efficiency
- Use for non-root execution (chiseled images have this user)
USER app - Chiseled images have no shell—use exec form only, no chains in final stage
&& - Include .dockerignore to exclude build artifacts
- Match runtime identifier () for self-contained builds
-r linux-x64 - Consider SHA pinning for production reproducibility
- 构建阶段使用SDK镜像,生产阶段使用runtime/aspnet镜像
- .NET 8+使用8080端口(而非80)
- 先复制.csproj文件再复制源代码,提升缓存效率
- 使用以非root用户运行(精简镜像默认包含该用户)
USER app - 精简镜像无Shell,最终阶段仅使用exec格式,不要使用链式命令
&& - 添加.dockerignore以排除构建产物
- 自包含构建需匹配运行时标识符()
-r linux-x64 - 生产环境可考虑固定SHA摘要以确保可复现性