首页 > 解决方案 > 为什么我们需要在 DockerFile 中为 Asp.net 核心提供多个复制指令

问题描述

目前我正在学习docker。我正在通过官方文档为 ASP.NET Core 创建 Docker 映像,该映像显示了具有以下内容的 DockerFile

FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "aspnetapp.dll"]

我最终成功地创建了图像和容器。

在这里,在 DockerFile 中有两条 COPY 指令。

第一个,仅从该目录复制 *.csproj 文件并将其粘贴到 docker 映像内的 /app 目录。

第二个,复制所有其他文件并将其粘贴到 docker 映像内的 /app 目录。

据了解,这个牵引COPY指令在做同样的事情。所以,我们可以写一个而不是两个不同的复制指令,它工作正常。像这样 -

COPY . ./
RUN dotnet restore
RUN dotnet publish -c Release -o out

那么,为什么我们使用两种不同的指令将文件复制到 docker 映像?它在两个复制指令下表现良好吗?

在第一COPY条指令中,有一条注释#Copy csproj and restore as distinct layers。它的实际含义或作用是什么?

标签: dockerasp.net-core

解决方案


原因是层次。在 Dockerfile 中,每个命令都会创建一个新的容器层。为了加速容器的构建,Dockers 缓存了这些没有任何变化的层,这意味着该命令不必再次运行;缓存层被简单地使用。但是,一旦发生了变化,Dockerfile 中的每一个后续命令都必须再次运行,因为该层和基于它构建的所有层现在都无效了。

两个复制行的原因是拉取所有 NuGet 包可能需要一段时间,而发生这种情况的唯一必要条件是项目文件。这些项目文件不太可能经常更改,因此可以缓存 NuGet 还原层。如果您复制了所有文件,那么对任何文件的任何更改都会使还原层无效,这意味着它基本上永远不会被缓存。


推荐阅读