Multi-stage Docker builds for .NET applications. Covers layer caching optimization, non-root user, health checks, and .NET-specific Dockerfile patterns. Trigger: Dockerfile, Docker, container, multi-stage build, container image.
From dotnet-ai-kitnpx claudepluginhub faysilalshareef/dotnet-ai-kit --plugin dotnet-ai-kitThis skill uses the workspace's default tool permissions.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Executes pre-written implementation plans: critically reviews, follows bite-sized steps exactly, runs verifications, tracks progress with checkpoints, uses git worktrees, stops on blockers.
base -> build -> publish -> final.csproj files first for layer caching (restore step)USER app or numeric UID)mcr.microsoft.com/dotnet/aspnet:{version}# Base runtime image
FROM mcr.microsoft.com/dotnet/aspnet:{version}-alpine AS base
WORKDIR /app
EXPOSE 8080
EXPOSE 8081
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:{version}-alpine AS build
WORKDIR /src
# Copy csproj files first for layer caching
COPY ["src/{Company}.{Domain}.Command/{Company}.{Domain}.Command.csproj", "src/{Company}.{Domain}.Command/"]
COPY ["src/{Company}.{Domain}.Shared/{Company}.{Domain}.Shared.csproj", "src/{Company}.{Domain}.Shared/"]
COPY ["Directory.Build.props", "."]
COPY ["Directory.Packages.props", "."]
RUN dotnet restore "src/{Company}.{Domain}.Command/{Company}.{Domain}.Command.csproj"
# Copy everything and build
COPY . .
WORKDIR "/src/src/{Company}.{Domain}.Command"
RUN dotnet build -c Release -o /app/build
# Publish stage
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish /p:UseAppHost=false
# Final stage
FROM base AS final
WORKDIR /app
# Non-root user
USER app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "{Company}.{Domain}.Command.dll"]
FROM base AS final
WORKDIR /app
USER app
COPY --from=publish /app/publish .
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
ENTRYPOINT ["dotnet", "{Company}.{Domain}.Command.dll"]
FROM mcr.microsoft.com/dotnet/runtime:{version}-alpine AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:{version}-alpine AS build
WORKDIR /src
# ... same build pattern ...
FROM base AS final
WORKDIR /app
USER app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "{Company}.{Domain}.Processor.dll"]
**/.git
**/.vs
**/bin
**/obj
**/node_modules
**/.env
**/Dockerfile*
**/.dockerignore
**/docker-compose*
**/*.md
**/tests
| .NET Version | SDK Image | Runtime Image |
|---|---|---|
| .NET 8 | sdk:8.0-alpine | aspnet:8.0-alpine |
| .NET 9 | sdk:9.0-alpine | aspnet:9.0-alpine |
| .NET 10 | sdk:10.0-alpine | aspnet:10.0-alpine |
| Anti-Pattern | Correct Approach |
|---|---|
| Single-stage build (bloated image) | Multi-stage: separate build and runtime |
| Copying all files before restore | Copy csproj first for layer caching |
| Running as root | Use USER app or numeric UID |
| Missing .dockerignore | Exclude bin, obj, .git, tests |
| Hardcoded .NET version | Match project TargetFramework |
# Find existing Dockerfiles
find . -name "Dockerfile*" -type f
# Check .NET version
grep -r "TargetFramework" --include="*.csproj" src/ | head -5
# Find .dockerignore
find . -name ".dockerignore" -type f
Directory.Build.props or .csproj