【问题标题】:Auto generated Dockerfile for Web .net core application为 Web .net 核心应用程序自动生成的 Dockerfile
【发布时间】:2019-10-29 13:22:11
【问题描述】:

在我看来,为 Web .net 核心应用程序自动生成的 Dockerfile 太大了,但为什么呢?为什么微软决定这样创建它?

这是我们在创建应用程序期间添加标志“添加 docker 支持”时自动生成的 Dockerfile:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY ["app/app.csproj", "app/"]
RUN dotnet restore "app/app.csproj"
COPY . .
WORKDIR "/src/app"
RUN dotnet build "app.csproj" -c Release -o /app/build

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

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

在我看来,它可以是这样的:

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster as build
WORKDIR /src
COPY ["app/app.csproj", "app/"]
RUN dotnet restore "app/app.csproj"
COPY . .
WORKDIR "/src/app"
RUN dotnet build "app.csproj" -c Release -o /app/build
RUN dotnet publish "app.csproj" -c Release -o /app/publish

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim
WORKDIR /app
EXPOSE 80
EXPOSE 443
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "app.dll"]

为什么微软决定首先 - 获取 aspnet:3.0-buster-slim 只是为了公开端口并稍后将它们用作最终版本?就像我的示例中那样,将这个图像作为最后一步得到它会短得多。我们还需要为 sdk:3.0-buster 使用 double From 吗(第一个命名为 build,第二个命名为 publish)?就像我的例子一样,可以一个一个地添加多个 RUN。

也许有一些技术建议为什么他们决定这样做? 谢谢!

【问题讨论】:

  • Dockerfile 中的第一个图像是 VS 用于调试的图像(按照惯例,有一个设置可以覆盖它并使用 VS 2019 中的特定命名阶段)。显然,您希望为此尽可能缩短周转时间。

标签: docker asp.net-core .net-core dockerfile


【解决方案1】:

Dockerfiledocker build . 命令使用的一系列步骤。至少需要三个步骤:

FROM some-base-image
COPY some-code-or-local-content
CMD the-entrypoint-command

随着我们的应用程序变得越来越复杂,添加了额外的步骤。就像恢复包和依赖项一样。为此使用如下命令:

RUN dotnet restore 

-或-

RUN npm install

或喜欢。随着它变得越来越困难,图像构建时间会增加,图像大小本身也会增加。

Docker 构建步骤会生成多个 Docker 映像并缓存它们。请注意以下输出:

$ docker build .
Sending build context to Docker daemon  310.7MB
Step 1/9 : FROM node:alpine
 ---> 4c6406de22fd
Step 2/9 : WORKDIR /app
 ---> Using cache
 ---> a6d9fba502f3
Step 3/9 : COPY ./package.json ./
 ---> dc39d95064cf
Step 4/9 : RUN npm install
 ---> Running in 7ccc864c268c 

注意step 2 是如何表达Using cache 的,因为 docker 意识到第 2 步之前的所有内容都与之前的构建步骤相同,因此使用之前构建命令中的缓存是安全的。

此模板的重点之一是构建高效的图像。 效率可以通过两种方式实现:

  1. 减少构建映像所需的时间
  2. 缩小最终图像的大小

#1 使用来自先前版本的缓存图像。将 dockerfile 划分为越来越依赖于之前的构建使得构建过程更快。只有高效写入 Dockerfile 才能依赖缓存。

通过将构建和发布的这些阶段分开,docker build . 命令将能够更好地使用 docker 文件中先前步骤中越来越多的缓存。

例如,对于 #2,请避免安装不需要的软件包。

请参阅 docker 文档以获取更多详细信息 here

【讨论】:

    【解决方案2】:

    默认情况下,VisualStudio 使用the Fast mode build 实际在本地计算机上构建您的项目,然后使用卷挂载将输出文件夹共享到容器。

    在快速模式下,Visual Studio 调用 docker build 时带有一个参数,告诉 Docker 只构建基础阶段。 Visual Studio 处理其余过程,而不考虑 Dockerfile 的内容。因此,当您修改 Dockerfile 时,例如自定义容器环境或安装额外的依赖项,您应该将修改放在第一阶段。放置在 Dockerfile 的构建、发布或最终阶段中的任何自定义步骤都不会执行。

    因此,您的问题的答案

    为什么微软决定首先 - 获取 aspnet:3.0-buster-slim 只是为了公开端口并在以后使用它们作为最终端口?

    为了在 VisualStudio 中提供优化的Fast 模式构建和调试,这是必要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      • 2018-05-14
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多