关于 dotnet-dockerfile
.NET Dockerfile Generator 是为 .NET 应用生成多阶段 Dockerfile 的技能。它帮助开发者依据 .NET 版本和应用类型选择镜像与部署模式,包括 chiseled 镜像和 Native AOT 等选项。
主要功能
- 01确定 .NET 版本和应用类型
- 02选择标准、chiseled 或 Native AOT 模式
- 03生成多项目解决方案构建模式
- 04提供自包含部署指导
- 05提供缓存、摘要固定和验证指导
适用场景
- 01为 ASP.NET Core 应用创建 Dockerfile
- 02容器化多项目 .NET 解决方案
- 03为 Native AOT 发布选择镜像
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jkappers/ agent-skills --skill dotnet-dockerfile安装后在 Claude Code 中输入/dotnet-dockerfile确认已加载。
详细介绍
.NET Dockerfile 生成器
为 .NET 应用生成适用于生产环境的多阶段 Dockerfile。
工作流
- 从项目文件中确定 .NET 版本(8、9 或 10),或询问用户
- 确定项目类型:ASP.NET Core Web 应用、API、工作服务或控制台应用
- 定位项目文件路径(例如,
src/MyApp/MyApp.csproj) - 选择优化方案:标准、chiseled(更小)或 Native AOT(最小/启动最快)
.NET 10 的重大变更:Ubuntu 现在是所有 .NET 容器映像的默认 Linux 发行版。不再提供 Debian 映像。
10.0、10.0-noble和10.0-noble-chiseled等标签均使用 Ubuntu 24.04 “Noble Numbat”。
映像选择指南
| 场景 | 运行时映像 | 压缩后大小 |
|---|---|---|
| 标准 ASP.NET | aspnet:10.0 | ~92 MB |
| 更小的占用空间 | aspnet:10.0-alpine | ~52 MB |
| 生产环境(推荐) | aspnet:10.0-noble-chiseled | ~53 MB |
| Azure Linux distroless | 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 映像:基于 Ubuntu,不含 shell 和包管理器,默认以非 root 用户运行。推荐用于生产环境。
Azure Linux distroless:可替代 chiseled,并提供 Microsoft 供应链安全保障。具备相似优势:不含 shell,默认以非 root 用户运行。
标准模式
# syntax=docker/dockerfile:1
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 source and 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"]
多项目解决方案模式
对于包含多个项目的解决方案,先复制所有 .csproj 文件:
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 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"]
自包含部署
将 .NET 运行时与应用捆绑,从而使用最小的 runtime-deps 映像:
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(启动最快)
编译为本机代码。映像最小(~12 MB),启动最快:
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-aotmcr.microsoft.com/dotnet/sdk:10.0-azurelinux3.0-aot
需要在 .csproj 中配置:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
限制:不支持运行时反射,并非所有库都兼容。
无 Dockerfile 的容器发布
.NET 10 支持直接通过 SDK 发布容器,无需 Dockerfile:
# Publish to local container runtime
dotnet publish --os linux --arch x64 /t:PublishContainer
# Publish directly to a registry (no Docker needed)
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"
项目文件配置:
<PropertyGroup>
<ContainerImageFormat>OCI</ContainerImageFormat>
<ContainerBaseImage>mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled</ContainerBaseImage>
<ContainerRepository>myapp</ContainerRepository>
<ContainerImageTag>1.0.0</ContainerImageTag>
</PropertyGroup>
开发阶段
添加开发阶段,用于本地开发和热重载:
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 .
缓存优化
使用 BuildKit 缓存挂载来缓存 NuGet 包:
RUN --mount=type=cache,target=/root/.nuget/packages \
dotnet restore
生产环境的 SHA 固定
固定确切的映像摘要,以确保可复现性和安全性:
FROM mcr.microsoft.com/dotnet/sdk:10.0@sha256:abc123... AS build
要查找当前摘要,请运行:
docker pull mcr.microsoft.com/dotnet/sdk:10.0
docker inspect --format='{{index .RepoDigests 0}}' mcr.microsoft.com/dotnet/sdk:10.0
必需的 .dockerignore
务必创建 .dockerignore:
**/bin/
**/obj/
**/.vs/
**/.vscode/
**/node_modules/
**/*.user
**/*.userosscache
**/*.suo
*.md
.git
.gitignore
Dockerfile*
docker-compose*
验证清单
- 构建阶段使用 SDK 映像,生产环境使用 runtime/aspnet
- .NET 8 及更高版本使用端口 8080(而非 80)
- 为提高缓存效率,先复制 .csproj 文件,再复制源代码
- 使用
USER app以非 root 用户运行(chiseled 映像包含此用户) - Chiseled 映像不含 shell——只能使用 exec 格式,最终阶段不要使用
&&链 - 添加 .dockerignore 以排除构建产物
- 自包含构建时匹配运行时标识符(
-r linux-x64) - 考虑在生产环境固定 SHA,以确保可复现性