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

工作流程

  1. Determine .NET version (8, 9, or 10) from project file or ask user
  2. Identify project type: ASP.NET Core web app, API, worker service, or console app
  3. Locate project file path (e.g.,
    src/MyApp/MyApp.csproj
    )
  4. 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
,
10.0-noble
, and
10.0-noble-chiseled
all use Ubuntu 24.04 "Noble Numbat".
  1. 从项目文件中确定.NET版本(8、9或10),或询问用户
  2. 识别项目类型:ASP.NET Core Web应用、API、工作服务或控制台应用
  3. 定位项目文件路径(例如:
    src/MyApp/MyApp.csproj
  4. 选择优化方式:标准、精简(更小体积)或Native AOT(体积最小/启动最快)
.NET 10中的重大变更:Ubuntu现在是所有.NET容器镜像的默认Linux发行版,不再提供Debian镜像。
10.0
10.0-noble
10.0-noble-chiseled
等标签均使用Ubuntu 24.04 "Noble Numbat"。

Image Selection Guide

镜像选择指南

ScenarioRuntime ImageCompressed Size
Standard ASP.NET
aspnet:10.0
~92 MB
Smaller footprint
aspnet:10.0-alpine
~52 MB
Production (recommended)
aspnet:10.0-noble-chiseled
~53 MB
Azure Linux distroless
aspnet:10.0-azurelinux3.0-distroless
~55 MB
Self-contained
runtime-deps:10.0-noble-chiseled
~22 MB
Native AOT
runtime-deps:10.0-noble-chiseled
~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应用
aspnet:10.0
~92 MB
更小占用空间
aspnet:10.0-alpine
~52 MB
生产环境(推荐)
aspnet:10.0-noble-chiseled
~53 MB
Azure Linux无发行版镜像
aspnet:10.0-azurelinux3.0-distroless
~55 MB
自包含部署
runtime-deps:10.0-noble-chiseled
~22 MB
Native AOT
runtime-deps:10.0-noble-chiseled
~12 MB
精简镜像(Chiseled images):基于Ubuntu,无Shell、无包管理器,默认以非root用户运行,推荐用于生产环境。
Azure Linux无发行版镜像:精简镜像的替代方案,具备微软供应链安全能力,同样拥有无Shell、默认非root运行等优势。

Standard Pattern

标准模式

dockerfile
undefined
dockerfile
undefined

syntax=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"]
undefined
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"]
undefined

Multi-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 /src

Copy 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"]
undefined
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"]
undefined

Self-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 --from=build /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 --from=build /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 --from=build /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["./MyApp"]
Dedicated AOT SDK images include native compilation prerequisites:
  • mcr.microsoft.com/dotnet/sdk:10.0-aot
    (Ubuntu, also tagged
    10.0-noble-aot
    )
  • mcr.microsoft.com/dotnet/sdk:10.0-alpine-aot
  • mcr.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 --from=build /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["./MyApp"]
专用AOT SDK镜像包含原生编译所需的依赖项:
  • mcr.microsoft.com/dotnet/sdk:10.0-aot
    (Ubuntu,也标记为
    10.0-noble-aot
  • mcr.microsoft.com/dotnet/sdk:10.0-alpine-aot
  • mcr.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
undefined

Publish 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
dotnet publish --os linux --arch x64 /t:PublishContainer
-p ContainerRegistry=ghcr.io
-p ContainerRepository=myorg/myapp

Multi-architecture publishing

多架构发布

dotnet publish /t:PublishContainer
-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"

**项目文件配置**:
```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 --from=build /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 --from=build /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 --mount=type=cache,target=/root/.nuget/packages \
    dotnet restore
使用BuildKit缓存挂载来缓存NuGet包:
dockerfile
RUN --mount=type=cache,target=/root/.nuget/packages \
    dotnet restore

SHA Pinning for Production

生产环境的SHA固定

Pin exact image digests for reproducibility and security:
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0@sha256:abc123... AS build
To 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.0

Required .dockerignore

必备的.dockerignore

Always create
.dockerignore
:
dockerignore
**/bin/
**/obj/
**/.vs/
**/.vscode/
**/node_modules/
**/*.user
**/*.userosscache
**/*.suo
*.md
.git
.gitignore
Dockerfile*
docker-compose*
务必创建
.dockerignore
文件:
dockerignore
**/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
    USER app
    for non-root execution (chiseled images have this user)
  • Chiseled images have no shell—use exec form only, no
    &&
    chains in final stage
  • Include .dockerignore to exclude build artifacts
  • Match runtime identifier (
    -r linux-x64
    ) for self-contained builds
  • Consider SHA pinning for production reproducibility
  • 构建阶段使用SDK镜像,生产阶段使用runtime/aspnet镜像
  • .NET 8+使用8080端口(而非80)
  • 先复制.csproj文件再复制源代码,提升缓存效率
  • 使用
    USER app
    以非root用户运行(精简镜像默认包含该用户)
  • 精简镜像无Shell,最终阶段仅使用exec格式,不要使用
    &&
    链式命令
  • 添加.dockerignore以排除构建产物
  • 自包含构建需匹配运行时标识符(
    -r linux-x64
  • 生产环境可考虑固定SHA摘要以确保可复现性