mcpField
D
dotnet-dockerfile

dotnet-dockerfile

github.com/jkappers云与 DevOps045 次安装36 周前更新
代码仓库

关于 dotnet-dockerfile

.NET Dockerfile Generator 是为 .NET 应用生成多阶段 Dockerfile 的技能。它帮助开发者依据 .NET 版本和应用类型选择镜像与部署模式,包括 chiseled 镜像和 Native AOT 等选项。

主要功能

  1. 01确定 .NET 版本和应用类型
  2. 02选择标准、chiseled 或 Native AOT 模式
  3. 03生成多项目解决方案构建模式
  4. 04提供自包含部署指导
  5. 05提供缓存、摘要固定和验证指导

适用场景

  1. 01为 ASP.NET Core 应用创建 Dockerfile
  2. 02容器化多项目 .NET 解决方案
  3. 03为 Native AOT 发布选择镜像

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jkappers/agent-skills --skill dotnet-dockerfile

安装后在 Claude Code 中输入/dotnet-dockerfile确认已加载。

详细介绍

.NET Dockerfile 生成器

为 .NET 应用生成适用于生产环境的多阶段 Dockerfile。

工作流

  1. 从项目文件中确定 .NET 版本(8、9 或 10),或询问用户
  2. 确定项目类型:ASP.NET Core Web 应用、API、工作服务或控制台应用
  3. 定位项目文件路径(例如,src/MyApp/MyApp.csproj)
  4. 选择优化方案:标准、chiseled(更小)或 Native AOT(最小/启动最快)

.NET 10 的重大变更:Ubuntu 现在是所有 .NET 容器映像的默认 Linux 发行版。不再提供 Debian 映像。10.0、10.0-noble 和 10.0-noble-chiseled 等标签均使用 Ubuntu 24.04 “Noble Numbat”。

映像选择指南

场景运行时映像压缩后大小
标准 ASP.NETaspnet:10.0~92 MB
更小的占用空间aspnet:10.0-alpine~52 MB
生产环境(推荐)aspnet:10.0-noble-chiseled~53 MB
Azure Linux distrolessaspnet:10.0-azurelinux3.0-distroless~55 MB
自包含runtime-deps:10.0-noble-chiseled~22 MB
Native AOTruntime-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-aot
  • mcr.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,以确保可复现性

评论

支持 Markdown