Reputation: 38417
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
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
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
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