为什么多步骤docker构建更好?

时间:2018-06-22 22:14:22

标签: docker .net-core dockerfile

我已经将dotnet核心应用程序从dotnet 2.0更新到2.1,我发现现在建议使用多步骤dockerfile。我读到,使用dotnet SDK在容器中构建应用程序,然后仅在运行时将其复制到其他容器中,效率更高。 https://github.com/dotnet/announcements/issues/18

我想知道为什么这样做会更好,因为我们如何通过2.0映像来做到这一点,该映像将在构建服务器(已安装dotnet 2.1 sdk)上运行dotnet publish MySolution.sln -c Release -o ./obj/Docker/publish,然后执行单步构建我们将生成的输出复制到图像上。

据称进行多步骤构建比较简单,但是对我来说,复制构建所需的一切,然后将结果复制到另一个容器对我来说似乎更为复杂。

这是多步骤Dockerfile的样子

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY myproject.csproj app/
RUN dotnet restore myproject.csproj
COPY . .
WORKDIR /src/Setting
RUN dotnet restore myproject.csproj
RUN dotnet build myproject.csproj -c Release -o /app

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

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

是第一步。

FROM microsoft/aspnetcore:2.0
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "Myproject.dll"]

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

  

我了解到,使用dotnet SDK在容器中构建应用程序,然后仅在运行时将其复制到其他容器中,效率更高。

我相信Docker的官方文档中的.Net Core 2.1之前已经存在此描述。

这仅仅是因为您只需要SDK来构建应用程序,但是如果您已经在其他地方构建了应用程序,则可以直接在运行时容器(而不是SDK容器)上运行它。当没有适用于ARM处理器的SDK时,我做了很多事情,我不得不在PC上构建应用程序,然后将其复制到目标设备。那不是那么容易,因为我总是遇到依赖关系问题,必须手动解决。

因此,几乎总是建议在要用于部署应用程序的计算机上构建应用程序。这样可以确保您的应用程序将根据确切的软件和硬件要求使用正确的设置进行构建。

因此,我总是将应用程序构建在目标部署设备(在SDK容器上)上,然后将构建的输出复制到运行时容器中。

现在您在问:为什么不简单地在SDK容器中运行应用程序?唯一的原因可能是因为它将比任何运行时容器大得多且重(因为它具有运行时环境+构建工具)。

答案 1 :(得分:0)

最终只使用了一个阶段构建,因为我们可以在CI服务器上构建应用。 CI服务器已安装SDK,但我们的容器仅使用运行时映像。如果您没有可用的dotnet sdk,或者要在容器上进行构建,那么从SDK映像进行构建可能会很有趣。

这是我的Dockerfile对于2.1的样子:

FROM microsoft/dotnet:2.1-aspnetcore-runtime
WORKDIR /app
EXPOSE 80
COPY Microservices/FooService/Foo/obj/Docker/publish .
ENTRYPOINT ["dotnet", "Foo.dll"]