为什么 ASP.NET 核心多阶段 Dockerfile 使用 4 个阶段

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

当您在 ASP.NET 核心站点的 Visual Studio 中单击 'Add Docker Support' 时,这是默认的多阶段 Dockerfile。

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"]

为什么他们选择使用四个阶段,从 base 阶段开始和结束。另外,为什么要使用相同的 build 基础图像创建 publish 阶段。为什么 Dockerfile 分三个阶段看起来不像这样:

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"]

这有什么我想念的优势吗?

文件有效等同于下面

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"]

现在他们可能选择 4 个构建阶段的原因可能是这两个中的任何一个

  • 演示
  • 未来的变化

所以它可能描绘了一个

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

2 个构建阶段的大小也与此相同。所以2阶段和4阶段没有明显区别。它变成了一种物质偏好、代表性等等。技术上没有什么不同

没有使用 4 个阶段的编程原因。

在第一阶段只是更改了配置。在第三阶段,图像没有改变。唯一使用 FROM build AS publish 有一个新的别名。

我认为没有必要处理 docker 的构建结构中的后期更改。 (4 阶段代码可能会这样做。)使用版本化图像,就像在您的示例中一样。例如。 2.0 而不是 latest。这样可以避免不兼容。如果build的方式会有变化,可以赶上。

docker 建议在没有指定 csproj 名称的情况下工作,就像使用 *.csproj 一样。这适用于大多数项目,生成大约 350MB 的图像大小。