api-versioning
API versioning strategies for ASP.NET Core. Covers Asp.Versioning library, URL segment,…
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
$ npx -y skills add codewithmukesh/dotnet-claude-kit --skill container-publish --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/container-publishContext preview
The summary Claude sees to decide when to auto-load this skill.
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
name: container-publish description: > 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".
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.
No project file changes needed. Just publish:
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.
<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>Authenticate with `docker login` first, then specify the registry:
# 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 (requires username prefix in repository)
dotnet publish /t:PublishContainer --os linux --arch x64 \
-p ContainerRegistry=docker.io \
-p ContainerRepository=myuser/myappBuild images for multiple platforms with a single publish:
<PropertyGroup>
<RuntimeIdentifiers>linux-x64;linux-arm64</RuntimeIdentifiers>
<ContainerRuntimeIdentifiers>linux-x64;linux-arm64</ContainerRuntimeIdentifiers>
</PropertyGroup>dotnet publish /t:PublishContainer
This produces an OCI Image Index — registries serve the correct architecture automatically.
# Bash — note the quoting for semicolons
dotnet publish /t:PublishContainer --os linux --arch x64 \
-p ContainerImageTags='"1.0.0;latest"'Or in the project file:
<ContainerImageTags>1.0.0;latest</ContainerImageTags>
No container runtime needed on the build machine. Useful for CI scanning:
dotnet publish /t:PublishContainer --os linux --arch x64 \
-p ContainerArchiveOutputPath=./images/myapp.tar.gz
# Scan with Trivy before pushing
trivy image --input ./images/myapp.tar.gz| ContainerFamily | Use Case | Shell | Size | |----------------|----------|-------|------| | *(default)* | General purpose (Debian) | Yes | ~220 MB | | `noble-chiseled` | Production (no shell) | No | ~110 MB | | `noble-chiseled-extra` | Production with localization (ICU) | No | ~120 MB | | `alpine` | Small size, has shell | Yes | ~112 MB |
<!-- 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`:
<PublishAot>true</PublishAot> <!-- SDK picks runtime-deps:10.0-noble-chiseled-aot automatically -->
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 }}<!-- BAD — ContainerImageName is deprecated --> <ContainerImageName>myapp</ContainerImageName> <!-- GOOD — use ContainerRepository --> <ContainerRepository>myapp</ContainerRepository>
# BAD — old approach, inconsistent across project types dotnet publish -p:PublishProfile=DefaultContainer # GOOD — use the MSBuild target directly dotnet publish /t:PublishContainer
# BAD on Windows — may produce a Windows container dotnet publish /t:PublishContainer # GOOD — explicitly target Linux dotnet publish /t:PublishContainer --os linux --arch x64
API versioning strategies for ASP.NET Core. Covers Asp.Versioning library, URL segment,…
Architecture conformance check: verifies an existing codebase against its declared…
Architecture selection advisor for .NET applications. Asks structured questions about domain…
.NET Aspire for cloud-native orchestration. Covers AppHost configuration, service defaults,…
Authentication and authorization for ASP.NET Core. Covers JWT bearer tokens, OpenID Connect,…
Autonomous iteration loops for .NET: drive a broken build or failing test suite to green with…