Help us improve
Share bugs, ideas, or general feedback.
From dotnet-claude-kit
Provides Docker containerization for .NET 10 apps: multi-stage builds, non-root users, health checks, .dockerignore, and Docker Compose for local development.
npx claudepluginhub codewithmukesh/dotnet-claude-kit --plugin dotnet-claude-kitHow this skill is triggered — by the user, by Claude, or both
Slash command
/dotnet-claude-kit:dockerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
1. **Multi-stage builds always** — Separate build and runtime stages. Build in the SDK image, run in the ASP.NET runtime image.
Containerizing .NET apps. Multi-stage Dockerfiles, SDK container publish (.NET 8+), rootless.
Builds and publishes .NET 10 container images without Dockerfiles using dotnet publish /t:PublishContainer. Configures chiseled images, multi-arch builds, MSBuild properties, and registry pushes.
Sets up multi-stage Dockerfiles and Docker Compose for .NET multi-container apps including Blazor web, API, worker services with Postgres, Redis, RabbitMQ.
Share bugs, ideas, or general feedback.
USER app by default since .NET 8. Never run as root in production..csproj files and restore before copying source code. This caches NuGet dependencies across builds.HEALTHCHECK in Dockerfile or configure in Docker Compose / orchestrator.# Stage 1: Build
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
# Copy project files and restore (cached layer)
COPY ["src/MyApp.Api/MyApp.Api.csproj", "src/MyApp.Api/"]
COPY ["src/MyApp.Domain/MyApp.Domain.csproj", "src/MyApp.Domain/"]
COPY ["Directory.Build.props", "."]
COPY ["Directory.Packages.props", "."]
RUN dotnet restore "src/MyApp.Api/MyApp.Api.csproj"
# Copy everything and build
COPY . .
RUN dotnet publish "src/MyApp.Api/MyApp.Api.csproj" \
-c Release \
-o /app/publish \
--no-restore
# Stage 2: Runtime
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
WORKDIR /app
# Non-root user (default in .NET 8+ images)
USER app
COPY --from=build /app/publish .
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD ["dotnet", "MyApp.Api.dll", "--urls", "http://localhost:8080/health/live"]
ENTRYPOINT ["dotnet", "MyApp.Api.dll"]
**/.git
**/.vs
**/bin
**/obj
**/node_modules
**/Dockerfile*
**/docker-compose*
**/tests
Key .NET-specific concerns — pass connection strings via environment, use depends_on with health checks:
services:
api:
build:
context: .
dockerfile: src/MyApp.Api/Dockerfile
ports:
- "5000:8080"
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ConnectionStrings__Default=Host=postgres;Database=myapp;Username=postgres;Password=postgres
- ConnectionStrings__Redis=redis:6379
depends_on:
postgres:
condition: service_healthy
# Add postgres/redis services with healthcheck — standard boilerplate
For solutions with multiple projects, restore only the necessary projects.
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
# Copy solution and all project files
COPY *.slnx .
COPY Directory.Build.props .
COPY Directory.Packages.props .
COPY src/**/*.csproj ./src/
# Restore project structure
RUN for file in src/**/*.csproj; do \
mkdir -p $(dirname $file) && mv $file $(dirname $file)/; \
done
RUN dotnet restore
COPY . .
RUN dotnet publish src/MyApp.Api -c Release -o /app/publish --no-restore
// In Program.cs — lightweight health endpoint for Docker
app.MapGet("/health/live", () => Results.Ok("healthy"))
.ExcludeFromDescription();
# BAD — SDK image is 900MB+, includes compilers
FROM mcr.microsoft.com/dotnet/sdk:10.0
COPY . .
RUN dotnet run
# GOOD — separate build and runtime, runtime image is ~200MB
FROM mcr.microsoft.com/dotnet/aspnet:10.0
# BAD — any source change invalidates the NuGet cache
COPY . .
RUN dotnet restore
# GOOD — copy only project files first, then restore
COPY ["src/MyApp.Api/MyApp.Api.csproj", "src/MyApp.Api/"]
RUN dotnet restore "src/MyApp.Api/MyApp.Api.csproj"
COPY . .
# BAD — running as root (security risk)
FROM mcr.microsoft.com/dotnet/aspnet:10.0
COPY --from=build /app .
ENTRYPOINT ["dotnet", "MyApp.Api.dll"]
# GOOD — use the built-in non-root user
FROM mcr.microsoft.com/dotnet/aspnet:10.0
USER app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "MyApp.Api.dll"]
| Scenario | Recommendation |
|---|---|
| Web API container | Multi-stage build with aspnet runtime image |
| Worker service | Multi-stage build with dotnet/runtime image |
| Local development | Docker Compose with service dependencies |
| CI builds | Multi-stage build (self-contained) |
| Image size optimization | Use Alpine variant + trimming for small images |
| Health monitoring | HEALTHCHECK instruction + /health endpoint |
| Secrets | Environment variables or mounted secrets, never in image |