Multi-Stage Dockerfiles for .NET Services
Cutting image size from 1.2 GB to 210 MB and why chiseled images matter for pull time on Kubernetes.
Our gateway image started as FROM mcr.microsoft.com/dotnet/sdk:8.0 — fine for dev, painful in prod.
Before
FROM mcr.microsoft.com/dotnet/sdk:8.0
WORKDIR /app
COPY . .
RUN dotnet publish -c Release -o out
ENTRYPOINT ["dotnet", "out/Gateway.dll"]
Image size: 1.2 GB. Every deploy pulled the full SDK layer across 30 nodes.
After
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["Gateway.csproj", "./"]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish /p:UseAppHost=false
FROM mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled AS final
WORKDIR /app
COPY --from=build /app/publish .
USER $APP_UID
ENTRYPOINT ["dotnet", "Gateway.dll"]
Image size: 210 MB. Pull time on cold nodes dropped from ~90s to ~15s.
docker , dotnet , images · Docker , .NET