Core Containers with multi-stage Docker builds

This short post introduces the concept of multi-stage Docker builds for ASP.NET Core applications.

Microsoft maintains two core images on Docker hub. The following are descriptions from the Docker hub pages:


This repository contains images that are used to compile/publish ASP.NET Core applications inside the container. This is different to compiling an ASP.NET Core application and then adding the compiled output to an image, which is what you would do when using the microsoft/aspnetcore image. These Dockerfiles use the microsoft/dotnet image as its base.


This repository contains images for running published ASP.NET Core applications. These images use the microsoft/dotnet image as its base. These images contain the runtime only. Use microsoft/aspnetcore-build to build ASP.NET Core apps inside the container.

Before multi-stage builds there were basically 2 options. The first option was to install the SDK on your computer or CI machine, build and package your app then build a container based on the ASP.NET Core runtime and package output. The second option was to use a container with the SDK already baked in, mount that container to a volume on your host, build and publish your app to that volume and finally, build a container based on the ASP.NET Core runtime and package output.

Multi-Stage Builds

Multi-stage builds allow developers to build their ASP.NET core projects in aspnetcore-build and copy the published output to an aspnetcore container in one Docker file without unnecessarily increasing the size of the final container. The following Docker file was taken from one of my Github projects.

FROM microsoft/aspnetcore-build:2.0.0-preview2 as builder
COPY . /workspace
WORKDIR /workspace
RUN mkdir /publish
RUN dotnet publish -o /publish src/aspnet-core-sample/aspnet-core-sample.csproj

FROM microsoft/aspnetcore:2.0.0-preview2
EXPOSE 80/tcp
COPY --from=builder /publish /app
ENTRYPOINT ["dotnet", "aspnet-core-sample.dll"]

A multi-stage build Docker file is simply a Docker file containing multiple FROM clauses. Each FROM clause is referred to as a stage. Traditionally, these stages would have been separate Docker files. This feature allows you to chain multiple steps in the image build process without complex glue scripts and CI processes.

You can read more about multi-stage builds on the Docker blog. You can also take a look at my sample Dockerfile on Github.