Muhammad Rehan Saeed
Muhammad Rehan Saeed

Reputation: 38417

Why does the ASP.NET Core Multi-Stage Dockerfile use 4 Stages

This is the default multi-stage Dockerfile when you click on 'Add Docker Support' in Visual Studio on an ASP.NET Core site.

FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY WebApplication1.sln ./
COPY WebApplication1/WebApplication1.csproj WebApplication1/
RUN dotnet restore
COPY . .
WORKDIR /src/WebApplication1
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "WebApplication1.dll"]

Why have they chosen to use four stages, starting and finishing with the base stage. Also, why create a publish stage using the same build base image. Why does the Dockerfile not look like this with three stages:

FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY WebApplication1.sln ./
COPY WebApplication1/WebApplication1.csproj WebApplication1/
RUN dotnet restore
COPY . .
WORKDIR /src/WebApplication1
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Release -o /app

FROM microsoft/aspnetcore:2.0 AS final
WORKDIR /app
EXPOSE 80
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "WebApplication1.dll"]

Is there some advantage to this that I am missing?

Upvotes: 9

Views: 1171

Answers (2)

androbin
androbin

Reputation: 1759

There is no programatic reason for using 4 stages.

In the first stage just configuration is changed. In the third stage the image is not changed. The only use of FROM build AS publish to have a new alias.

I think there is no use of taking care of later changes in the build structure of docker. (The 4 stage code probably does that.) Use versioned images, just like in your example. E.g. 2.0 instead of latest. This way incomatibility can be avoided. If there will be changes in the way of the build, you can catch up with it.

The docker recommendation works with no csproj name specified, as using *.csproj. That works for most of the projects, producing about 350MB image-size.

Upvotes: 2

Tarun Lalwani
Tarun Lalwani

Reputation: 146510

The file effectively equivalent to below

FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY WebApplication1.sln ./
COPY WebApplication1/WebApplication1.csproj WebApplication1/
RUN dotnet restore
COPY . .
WORKDIR /src/WebApplication1
RUN dotnet build -c Release -o /app
RUN dotnet publish -c Release -o /app

FROM microsoft/aspnetcore:2.0 AS base
EXPOSE 80
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "WebApplication1.dll"]

Now the reason they may have chosen 4 build stage might be any of the two

  • Presentational
  • Future changes

So it may be that it depicts a

base -> build -> publish -> deploy the build

The size with 2 build stage would also the same as this one. So there is no obvious difference between the 2 stage and the 4 stage. It becomes a matter preference, representation and all. Nothing technologically different

Upvotes: 3

Related Questions