The Problem with Naive Docker Images
A naive FROM mcr.microsoft.com/dotnet/sdk:10.0 image ships the entire SDK — over 800MB. Production needs only the runtime.
Multi-Stage Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY ["MyApp.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:10.0-alpine AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]
âš¡
Alpine-based images are ~80MB vs ~200MB for Debian. Use them for production unless you need glibc-dependent native libraries.
Layer Caching Tip
Copy the .csproj and run dotnet restore before copying source code. This caches the restore layer and speeds up rebuilds dramatically.
Result
Final image size: 98MB vs 820MB naive. Build time with cache: 12 seconds.