docker - 为什么我们需要在 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
。它的实际含义或作用是什么?
解决方案
原因是层次。在 Dockerfile 中,每个命令都会创建一个新的容器层。为了加速容器的构建,Dockers 缓存了这些没有任何变化的层,这意味着该命令不必再次运行;缓存层被简单地使用。但是,一旦发生了变化,Dockerfile 中的每一个后续命令都必须再次运行,因为该层和基于它构建的所有层现在都无效了。
两个复制行的原因是拉取所有 NuGet 包可能需要一段时间,而发生这种情况的唯一必要条件是项目文件。这些项目文件不太可能经常更改,因此可以缓存 NuGet 还原层。如果您复制了所有文件,那么对任何文件的任何更改都会使还原层无效,这意味着它基本上永远不会被缓存。
推荐阅读
- c# - 错误!'对象不能从 DBNull 转换为其他类型。' C# 使用方法 sum()
- python - 如何在 Dask 任务执行之间保留一些 Python 对象状态?
- c - filename_lookup 在 4.18 的 RHEL 8 中不可用,替代方案是什么?
- mkmapview - 在 SwiftUI 中为 MKMapView 添加“显示用户位置”按钮的正确方法是什么?
- marklogic - 如何在路径范围索引中使用谓词
- android - 由于 V28 元素,构建失败,但目标是 v26
- python - 哪些对象类型可用于决策树中的特征?我需要将我的“对象”类型转换为另一种类型吗?
- java - 无法启动 appium 检查器会话:以代码 255 退出
- kubernetes-ingress - 从 Ingressgateway 重试
- python - 加快向前看,落后于 pandas DataFrame 中的时间序列搜索