Docker  

What Is a Multi-Stage Dockerfile and how to create it

What Is a Multi-Stage Dockerfile?

A multi-stage Dockerfile is a Docker build optimization technique that lets you use multiple FROM statements in one Dockerfile.

Each FROM starts a new build stage, and you can copy only what’s needed from one stage to another — for example:

  • Build your app in one stage (with SDK),

  • Run your app in another environment (with a lightweight runtime).

Why use it?

  • Reduces final image size (up to 70%)

  • Improves security (no compiler or build tools left)

  • Makes builds faster and cleaner

How It Works (Simplified Flow)

  1. Stage 1: Use .NET SDK image → build and publish the app.

  2. Stage 2: Use .NET Runtime image → copy the published files → run the app.

Best Example — Multi-Stage Dockerfile for .NET Core Web API

# ================================
# Stage 1: Build and Publish
# ================================
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src

# Copy csproj and restore dependencies (do this first for caching)
COPY ["MyApp/MyApp.csproj", "MyApp/"]
RUN dotnet restore "MyApp/MyApp.csproj"

# Copy everything else and build
COPY . .
WORKDIR "/src/MyApp"
RUN dotnet publish -c Release -o /app/publish /p:UseAppHost=false


# ================================
# Stage 2: Runtime (Final Image)
# ================================
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app

# Copy only the published output from build stage
COPY --from=build /app/publish .

# Set environment and entry point
ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080

ENTRYPOINT ["dotnet", "MyApp.dll"]

What’s Happening Here

StageBase ImagePurposeOutput
buildmcr.microsoft.com/dotnet/sdk:8.0Compile, restore, publish the app/app/publish folder
finalmcr.microsoft.com/dotnet/aspnet:8.0Run the published appLightweight runtime image

Result

  • Final image contains only your app + runtime.

  • No SDK, build tools, or temporary files.

  • Perfect for production use in Kubernetes, Azure App Service, or Azure VM.

Command Summary

# Build image
docker build -t myapp:latest .

# Run container
docker run -d -p 8080:8080 myapp

Pro Tips

  • Use alpine variant for smaller image:

    FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
    
  • Add .dockerignore to skip logs, .git, bin, obj.

  • Use BuildKit for faster caching:

    DOCKER_BUILDKIT=1 docker build .
    

Conclusion

Multi-stage Docker builds are the gold standard for modern .NET deployments.
They make your container:

  • Smaller

  • Faster

  • More secure

When deploying to Kubernetes or Azure, this approach ensures every image is clean, efficient, and production-ready.