Understanding Multistage builds in Docker
A multi-stage build in Docker allows you to use multiple FROM statements in a single Dockerfile to create separate stages for building and running an application. For example, in the first stage, you can use a large image with the SDK (e.g., mcr.microsoft.com/dotnet/sdk) to compile and publish the application. In the second stage, you copy the build output to a lightweight runtime-only image (e.g., mcr.microsoft.com/dotnet/aspnet) to create the final container. This approach significantly reduces the size of the final image because only the application and its dependencies are included, while the build tools and intermediate files are discarded. This results in smaller, more secure, and more efficient images.
Each image used in a multi-stage Docker build can have a specific tag that identifies the exact version or variant of the image. For example, in the build stage, you might use a tagged SDK image like mcr.microsoft.com/dotnet/sdk:9.0 to ensure the application is compiled with a specific .NET version. In the final stage, you can use a lightweight runtime image such as mcr.microsoft.com/dotnet/aspnet:9.0-alpine for optimized hosting. Tags ensure consistency by locking each stage to a specific version of the base image, preventing unexpected changes from upstream image updates. This approach improves reproducibility, as each stage is built with a clearly defined, immutable environment.
Here’s an example of a multi-stage Dockerfile for a .NET 9 Web API application, demonstrating how to use the SDK image for building the application and the runtime image for the final container.
Multi-Stage Dockerfile
Explanation of the Dockerfile
Stage 1: Build the Application
- Base Image:
mcr.microsoft.com/dotnet/sdk:9.0- Includes the full .NET SDK for building and publishing the application.
- Steps:
- Restores dependencies using
dotnet restore. - Builds the application in Release mode.
- Publishes the application to the
/app/publishfolder, optimized for runtime.
- Restores dependencies using
- Base Image:
Stage 2: Runtime Image
- Base Image:
mcr.microsoft.com/dotnet/aspnet:9.0-alpine- A lightweight runtime-only image optimized for production.
- Steps:
- Copies the published application from the
buildstage. - Exposes ports
5000(HTTP) and5001(HTTPS) for the app. - Sets the entry point to run the
.dllfile usingdotnet.
- Copies the published application from the
- Base Image:
How to Build and Run
Build the Docker Image:
Run the Docker Container:
Access the Application:
- HTTP:
http://localhost:5000 - HTTPS:
https://localhost:5001
- HTTP:
Benefits of Multi-Stage Builds in This Example
- Smaller Final Image:
- The final image only includes the runtime dependencies, reducing its size significantly compared to the build stage.
- Better Security:
- No build tools or unnecessary files are included in the runtime image, minimizing the attack surface.
- Efficient Development Workflow:
- Clearly separates the build process and runtime environment.
Comments
Post a Comment