为什么我们需要Asp.net核心DockerFile中的多拷贝指令

为什么我们需要Asp.net核心DockerFile中的多拷贝指令,docker,asp.net-core,Docker,Asp.net Core,目前我正在学习docker。我正在浏览官方文档,为ASP.NET Core创建Docker映像,该映像显示具有以下内容的Docker文件 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 bu

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

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中,我们有两条复制指令

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

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

据了解,这两个
复制
指令是在做同样的事情。因此,我们可以编写一个复制指令,而不是两个不同的复制指令,它工作得很好。像这样-

COPY . ./
RUN dotnet restore
RUN dotnet publish -c Release -o out
那么,为什么我们使用两种不同的指令将文件复制到docker image?它在双拷贝指令下运行良好吗


在第一条
COPY
指令中,有一条注释
#COPY csproj并将其还原为不同的层
。它实际上意味着什么

原因是分层。在Dockerfile中,每个命令都会创建一个新的容器层。为了加快容器的构建,Dockers缓存这些层,在这些层中没有任何更改,这意味着该命令不必再次运行;只需使用缓存层。但是,一旦发生了更改,Dockerfile中的每个后续命令都必须再次运行,因为该层及其上构建的所有层现在都无效


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

原因是层。在Dockerfile中,每个命令都会创建一个新的容器层。为了加快容器的构建,Dockers缓存这些层,在这些层中没有任何更改,这意味着该命令不必再次运行;只需使用缓存层。但是,一旦发生了更改,Dockerfile中的每个后续命令都必须再次运行,因为该层及其上构建的所有层现在都无效

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