Container Publish

codewithmukesh/dotnet-claude-kit/skills/container-publish

作者 codewithmukesh23300897f4d1无许可证754 个星标收录于 2026年10月8日更新于 2026年10月8日仓库2个月前更新

Dockerfile-less containerization using the .NET 10 SDK container publishing feature. Covers MSBuild properties, chiseled images, multi-arch builds, and registry publishing — all without writing a Dockerfile. Load this skill when the user wants to containerize without a Dockerfile, or mentions "dotnet publish container", "PublishContainer", "ContainerRepository", "ContainerFamily", "chiseled", "distroless", "container publish", "SDK container", "no Dockerfile", or "containerize without Docker".

仅含说明DevOps & Cloud
AI 生成的概览

使用 .NET 10 SDK 容器发布功能,无需 Dockerfile 即可容器化 .NET 应用。

功能
说明如何直接通过 dotnet publish /t:PublishContainer 构建符合 OCI 规范的容器镜像,而无需编写 Dockerfile。内容涵盖 ContainerRepository、ContainerFamily、ContainerPort 等 MSBuild 容器属性,chiseled 与 distroless 基础镜像变体,多架构构建,多标签,tar 包输出,以及推送到 ghcr.io、Azure Container Registry 和 Docker Hub 等仓库。此外还列出反模式,并给出在 SDK 发布与 Dockerfile 之间取舍的决策指南。
适用场景
适用于在不编写 Dockerfile 的情况下容器化 .NET 应用,或用户提到 dotnet publish container、PublishContainer、ContainerRepository、ContainerFamily、chiseled、distroless 或 containerize without Docker 时。也适合在 CI 中配置多架构镜像构建或仓库推送。不适用于 SDK 无法发布的工作负载,例如 Azure Functions 或需要原生操作系统软件包的镜像。
运行要求
不附带脚本,仅为说明文档。需要 .NET 10 SDK,以及用于本地镜像输出和推送的 Docker 守护进程或镜像仓库访问权限。推送到仓库前需先完成身份验证,例如 docker login、az acr login 或 CI 令牌;使用 tar 包输出则无需容器运行时。

Container Publishing (No Dockerfile)

Core Principles

  1. No Dockerfile needed — The .NET 10 SDK builds OCI-compliant container images directly from dotnet publish /t:PublishContainer. No Dockerfile to write or maintain.
  2. Chiseled images for production — Use noble-chiseled base images: no shell, no package manager, 7 Linux components vs 100+. Smallest attack surface.
  3. Non-root by default — .NET 10 container images run as the app user automatically. Never override to root in production.
  4. Configuration in the .csproj — All container settings are MSBuild properties, versioned with your project. No separate files to drift.

Patterns

Minimal Container Publish

No project file changes needed. Just publish:

bash
dotnet publish /t:PublishContainer --os linux --arch x64

This creates a container image in your local Docker daemon using the default aspnet:10.0 base image.

Production-Ready .csproj Configuration

xml
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>    <TargetFramework>net10.0</TargetFramework>    <ContainerRepository>mycompany/myapp-api</ContainerRepository>    <ContainerFamily>noble-chiseled</ContainerFamily>  </PropertyGroup>
  <ItemGroup>    <ContainerPort Include="8080" Type="tcp" />    <ContainerEnvironmentVariable Include="ASPNETCORE_HTTP_PORTS" Value="8080" />    <ContainerEnvironmentVariable Include="DOTNET_EnableDiagnostics" Value="0" />    <ContainerLabel Include="org.opencontainers.image.vendor" Value="MyCompany" />  </ItemGroup>
</Project>

Publishing to a Registry

Authenticate with docker login first, then specify the registry:

bash
# GitHub Container Registrydocker login ghcr.iodotnet publish /t:PublishContainer --os linux --arch x64 \    -p ContainerRegistry=ghcr.io \    -p ContainerImageTag=1.0.0
# Azure Container Registryaz acr login --name myregistrydotnet publish /t:PublishContainer --os linux --arch x64 \    -p ContainerRegistry=myregistry.azurecr.io
# Docker Hub (requires username prefix in repository)dotnet publish /t:PublishContainer --os linux --arch x64 \    -p ContainerRegistry=docker.io \    -p ContainerRepository=myuser/myapp

Multi-Architecture Images

Build images for multiple platforms with a single publish:

xml
<PropertyGroup>    <RuntimeIdentifiers>linux-x64;linux-arm64</RuntimeIdentifiers>    <ContainerRuntimeIdentifiers>linux-x64;linux-arm64</ContainerRuntimeIdentifiers></PropertyGroup>
bash
dotnet publish /t:PublishContainer

This produces an OCI Image Index — registries serve the correct architecture automatically.

Multiple Tags

bash
# Bash — note the quoting for semicolonsdotnet publish /t:PublishContainer --os linux --arch x64 \    -p ContainerImageTags='"1.0.0;latest"'

Or in the project file:

xml
<ContainerImageTags>1.0.0;latest</ContainerImageTags>

Save as Tarball (No Docker Required)

No container runtime needed on the build machine. Useful for CI scanning:

bash
dotnet publish /t:PublishContainer --os linux --arch x64 \    -p ContainerArchiveOutputPath=./images/myapp.tar.gz
# Scan with Trivy before pushingtrivy image --input ./images/myapp.tar.gz

Chiseled Image Variants

ContainerFamilyUse CaseShellSize
(default)General purpose (Debian)Yes~220 MB
noble-chiseledProduction (no shell)No~110 MB
noble-chiseled-extraProduction with localization (ICU)No~120 MB
alpineSmall size, has shellYes~112 MB
xml
<!-- Standard chiseled (InvariantGlobalization=true) --><ContainerFamily>noble-chiseled</ContainerFamily>
<!-- Chiseled with ICU for localization --><ContainerFamily>noble-chiseled-extra</ContainerFamily>

For Native AOT, the SDK auto-selects chiseled-aot:

xml
<PublishAot>true</PublishAot><!-- SDK picks runtime-deps:10.0-noble-chiseled-aot automatically -->

CI/CD with GitHub Actions

yaml
jobs:  publish:    runs-on: ubuntu-latest    permissions:      packages: write    steps:      - uses: actions/checkout@v5      - uses: actions/setup-dotnet@v5        with:          dotnet-version: '10.0.x'      - uses: docker/login-action@v3        with:          registry: ghcr.io          username: ${{ github.actor }}          password: ${{ secrets.GITHUB_TOKEN }}      - run: |          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 }}

Anti-patterns

Don't Use the Deprecated Property Names

xml
<!-- BAD — ContainerImageName is deprecated --><ContainerImageName>myapp</ContainerImageName>
<!-- GOOD — use ContainerRepository --><ContainerRepository>myapp</ContainerRepository>

Don't Use PublishProfile=DefaultContainer

bash
# BAD — old approach, inconsistent across project typesdotnet publish -p:PublishProfile=DefaultContainer
# GOOD — use the MSBuild target directlydotnet publish /t:PublishContainer

Don't Forget to Target Linux

bash
# BAD on Windows — may produce a Windows containerdotnet publish /t:PublishContainer
# GOOD — explicitly target Linuxdotnet publish /t:PublishContainer --os linux --arch x64

Don't Skip Authentication Before Push

bash
# BAD — fails with CONTAINER1013 errordotnet publish /t:PublishContainer -p ContainerRegistry=ghcr.io
# GOOD — authenticate firstdocker login ghcr.iodotnet publish /t:PublishContainer -p ContainerRegistry=ghcr.io

Don't Use SDK Publishing When You Need OS Packages

xml
<!-- BAD — SDK container publish cannot run apt-get or install native packages --><!-- There is no RUN equivalent -->
<!-- GOOD — create a custom base image with a Dockerfile first, then reference it --><ContainerBaseImage>myregistry/custom-base:1.0</ContainerBaseImage>

Decision Guide

ScenarioRecommendation
Standard ASP.NET Core APISDK container publishing with noble-chiseled
Worker service / console appSDK container publishing (native .NET 10 support)
Needs native OS packagesDockerfile (or custom base image + SDK publishing)
Azure FunctionsDockerfile (not supported by SDK publishing)
CI without Docker daemonTarball output with ContainerArchiveOutputPath
Multi-arch deployment (x64 + arm64)ContainerRuntimeIdentifiers property
Production image sizenoble-chiseled (~110 MB) or Native AOT (~10 MB)
Local developmentdotnet publish /t:PublishContainer --os linux --arch x64
Registry pushContainerRegistry + docker login

来源与署名

来源:codewithmukesh/dotnet-claude-kit位于skills/container-publish提交2330089

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架

更多来自 codewithmukesh/dotnet-claude-kit 的技能

Wrap Up

codewithmukesh

在会话结束时把已完成工作、待办任务与经验写入交接文件,并在会话开始时重新载入。

Productivity & Workflow7542个月前更新

Workflow Mastery

codewithmukesh

Claude Code workflow mastery for .NET developers. Covers parallel execution with git worktrees, plan mode strategy, verification loops, auto-formatting hooks, permission setup for dotnet CLI, prompting techniques, subagent patterns, and context discipline — token budget management, MCP-first navigation, lazy loading, and subagent isolation — all adapted for the .NET ecosystem. Load this skill when setting up Claude Code for a .NET project, optimizing workflows, running parallel sessions, when context is running low or sessions feel sluggish, when exploring a large codebase efficiently, or when the user mentions "productivity", "workflow", "parallel", "worktree", "plan mode", "permissions", "hooks", "10x", "setup Claude Code", "speed up development", "context", "tokens", "budget", "running out of context", "too many files", or "large codebase". Inspired by tips from Boris Cherny (creator of Claude Code) and the Anthropic team.

待分类7542个月前更新

Vertical Slice

codewithmukesh

指导 .NET 开发者采用垂直切片架构组织应用,涵盖功能文件夹、端点分组与处理程序模式。

Software Development7542个月前更新

Testing

codewithmukesh

Testing strategy for .NET 10 applications. Covers xUnit v3, WebApplicationFactory for integration tests, Testcontainers for real database testing, Verify for snapshot testing, and the AAA pattern. Load this skill when writing tests, setting up test infrastructure, reviewing test coverage, or when the user mentions "test", "xUnit", "WebApplicationFactory", "Testcontainers", "integration test", "unit test", "bUnit", "snapshot test", "Verify", "test coverage", "AAA pattern", "WireMock", or "FakeTimeProvider".

待分类7542个月前更新

Tdd

codewithmukesh

Guided test-driven development workflow for .NET 10 using xUnit v3, WebApplicationFactory, Testcontainers, and Verify snapshots. Follows the strict red-green-refactor cycle. Use when: "TDD", "test-driven", "let's TDD this", "red green refactor", "write the test first", or when building a feature with clear acceptance criteria.

待分类7542个月前更新

Spec

codewithmukesh

通过结构化提问,把模糊的功能想法转化为双方确认并持久化的规格说明文件。

Productivity & Workflow7542个月前更新