A Docker Multi-Stage build is a capability introduced in Docker 18.06, and it allows you to shrink the image size for your applications significantly.
The fundamental problem is that all your build and runtime dependencies must be included in the final image during development. Still, you don’t need most of them once your application is deployed to production.
For example, You’re building a Node.js app and using Yarn for dependency management — Your Node_modules directory will contain thousands of files and take up a lot of space in the final image.
Of course, you can solve this problem by splitting your code into two separate images: One for development and another for production. But that means maintaining two images and having to keep them synchronized with each other.
The Multi-Stage build feature allows you to define two or more build stages that produce artifacts with different properties.
The first stage, for example, is responsible for building dependencies on your source code. It produces a “flat” image that includes all the necessary files for development.
The second stage copies your compiled application binaries to an empty image, producing a “thin” image that’s just the size you need for production.
Let’s have a look at the following Dockerfile code example with a .NET application. The application has two stages. The first stage (AS Build) copies the .NET project into the src directory and builds the app.
The second stage (AS Prod) copies the published application from the /app directory and configure the dotnet entry point to run the app.
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build WORKDIR /src COPY strongpass.csproj . RUN dotnet restore COPY . . RUN dotnet publish -c release -o /app FROM mcr.microsoft.com/dotnet/runtime AS Prod WORKDIR /app EXPOSE 80 EXPOSE 443 COPY --from=build /app . ENTRYPOINT ["dotnet", "strongpass.dll"]
The purpose of the multi-stage builds is to produce an image that can only run the application and is light.