运维部署
需要不写 Dockerfile 就把 .NET 10…
无需编写 Dockerfile,使用 .NET 10 SDK 的 dotnet publish /t:PublishContainer 将 ASP.NET Core、Worker 或控制台应用发布为生产可用的容器镜像。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
需要不写 Dockerfile 就把 .特定
解决思路
- 无需写 Dockerfile:用 .NET 10 SDK 直接从 dotnet publish /t:PublishContainer 构建 OCI 兼容容器镜像。
- 生产环境优先用 chiseled 镜像:选择 noble-chiseled 基础镜像,它没有 shell、没有包管理器,Linux 组件从 100+ 降到 7,攻击面最小。
- 默认非 root:.NET 10 容器镜像自动以 app 用户运行;生产环境不要覆盖为 root。
- 配置放在 .csproj:所有容器设置都用 MSBuild 属性,随项目版本化,避免单独文件漂移。
- 最小发布:无需修改项目文件,直接运行 dotnet publish /t:PublishContainer --os linux --arch x64;它使用默认 aspnet:10.0 基础镜像,在本机 Docker daemon 创建镜像。
- 标准 ASP.NET Core API、Worker Service 或控制台应用都可用 SDK 容器发布;生产环境选择 noble-chiseled,并按需使用下面的 .csproj 配置。
- 生产可用 .csproj:设置 TargetFramework 为 net10.0。
- 生产可用 .csproj:用 ContainerRepository 指定镜像仓库,例如 mycompany/myapp-api。
- 生产可用 .csproj:用 ContainerFamily 指定 noble-chiseled。
- 生产可用 .csproj:用 ContainerPort Include="8080" Type="tcp" 声明容器端口。
- 生产可用 .csproj:用 ContainerEnvironmentVariable 设置 ASPNETCORE_HTTP_PORTS=8080。
- 生产可用 .csproj:用 ContainerEnvironmentVariable 设置 DOTNET_EnableDiagnostics=0。
- 生产可用 .csproj:用 ContainerLabel 设置 org.opencontainers.image.vendor=MyCompany。
- 发布到 GitHub Container Registry:先 docker login ghcr.io,再运行 dotnet publish /t:PublishContainer --os linux --arch x64 -p ContainerRegistry=ghcr.io -p ContainerImageTag=1.0.0。
- 发布到 Azure Container Registry:先 az acr login --name myregistry,再运行 dotnet publish /t:PublishContainer --os linux --arch x64 -p ContainerRegistry=myregistry.azurecr.io。
- 发布到 Docker Hub:仓库需带用户名前缀,运行 dotnet publish /t:PublishContainer --os linux --arch x64 -p ContainerRegistry=docker.io -p ContainerRepository=myuser/myapp。
- 多架构镜像:在 .csproj 中设置 RuntimeIdentifiers 为 linux-x64;linux-arm64,并设置 ContainerRuntimeIdentifiers 为 linux-x64;linux-arm64;然后运行 dotnet publish /t:PublishContainer。该命令生成 OCI Image Index,registry 会自动提供正确架构。
- 多个标签(Bash):给分号加引号,运行 dotnet publish /t:PublishContainer --os linux --arch x64 -p ContainerImageTags='"1.0.0;latest"'。
- 多个标签(项目文件):设置 <ContainerImageTags>1.0.0;latest</ContainerImageTags>。
- 保存为 tarball(无需 Docker):构建机不需要容器运行时,适合 CI 扫描;运行 dotnet publish /t:PublishContainer --os linux --arch x64 -p ContainerArchiveOutputPath=./images/myapp.tar.gz。
- 扫描 tarball:推送前用 trivy image --input ./images/myapp.tar.gz 扫描。
- Chiseled 变体:默认 Debian 镜像用于通用场景,有 shell,约 220 MB。
- Chiseled 变体:noble-chiseled 用于生产,无 shell,约 110 MB。
- Chiseled 变体:noble-chiseled-extra 用于需要本地化 ICU 的生产场景,无 shell,约 120 MB。
- Chiseled 变体:alpine 体积小且有 shell,约 112 MB。
- 配置标准 chiseled:设置 <ContainerFamily>noble-chiseled</ContainerFamily>(配合 InvariantGlobalization=true)。
- 配置带 ICU 的 chiseled:设置 <ContainerFamily>noble-chiseled-extra</ContainerFamily>。
- Native AOT:设置 <PublishAot>true</PublishAot> 后,SDK 自动选择 chiseled-aot 基础镜像(runtime-deps:10.0-noble-chiseled-aot)。
- GitHub Actions CI/CD:job publish 运行在 ubuntu-latest,权限 packages: write;步骤依次是 actions/checkout@v5、actions/setup-dotnet@v5(dotnet-version: '10.0.x')、docker/login-action@v3(registry: ghcr.io,username: ${{ github.actor }},password: ${{ secrets.GITHUB_TOKEN }}),然后运行 dotnet publish src/MyApp.Api/MyApp.Api.csproj /t:PublishContainer --os linux --arch x64 -p ContainerRegistry=ghcr.io -p ContainerRepository=${{ github.repository_owner }}/myapp -p ContainerImageTag=${{ github.sha }}。
- 不要使用已弃用属性名:用 <ContainerRepository>myapp</ContainerRepository>,不要用 <ContainerImageName>myapp</ContainerImageName>。
- 不要使用 PublishProfile=DefaultContainer:用 dotnet publish /t:PublishContainer,不要用 dotnet publish -p:PublishProfile=DefaultContainer。
- 不要忘记目标 Linux:在 Windows 上显式运行 dotnet publish /t:PublishContainer --os linux --arch x64,避免产生 Windows 容器。
- 推送前不要跳过认证:先 docker login,否则可能因 CONTAINER1013 失败。
- 需要 OS 包时不要用 SDK 发布:SDK 容器发布不能执行 apt-get 或安装原生包,没有 RUN 等价物;应先用 Dockerfile 创建自定义基础镜像,再通过 <ContainerBaseImage>myregistry/custom-base:1.0</ContainerBaseImage> 引用。
适用边界 · 注意事项
- 需要安装原生 OS 包、执行 apt-get 或自定义 RUN 层时,不使用 SDK 容器发布;改用 Dockerfile 或自定义基础镜像。
- Azure Functions 不被 SDK 容器发布支持,应改用 Dockerfile。
- 需要 Windows 容器或非 Linux 目标时,不依赖默认发布;应显式选择目标或改用 Dockerfile。