首页 > 其他分享 >[转]Dockerfile:ADD VS COPY (结论:建议都使用COPY)

[转]Dockerfile:ADD VS COPY (结论:建议都使用COPY)

时间:2022-09-26 11:23:45浏览次数:83  
标签:tmp tar URL ADD VS 指令 COPY

这篇博文将帮助您理解两个类似的Dockerfile指令(ADD和COPY)之间的区别,以及它们如何成为现在的样子,以及我们对您应该使用哪条指令的建议。 (提示:不是ADD) 从Dockerfile构建Docker镜像时,您可以选择两个指令将目录/文件添加到镜像:ADD和COPY。两条指令都遵循相同的基本形式,并完成了几乎相同的事情:

ADD <src>... <dest>
COPY <src>... <dest>
复制代码

在这两种情况下,都会复制目录或文件()并将其添加到指定的路径的容器的文件系统中。

因此,如果两条指令都是相同的,为什么它们都存在,您应该使用哪一条?请仔细阅读,找出答案。

如果您对ADD和COPY的细微差别不感兴趣,只想回答“我应该使用哪一个?”,您只需要知道:使用COPY。

故事起源

与COPY指令不同的是,ADD从一开始就是Docker的一部分,除了从构建上下文中复制文件之外,还支持一些其他技巧。

ADD指令允许您使用URL作为参数。提供URL时,将从URL下载文件并将其复制到。

ADD http://foo.com/bar.go /tmp/main.go
复制代码

上面的文件将从指定的URL下载并添加到容器的文件系统/tmp/main.go中。另一种形式可以让你简单地为下载的文件指定目标目录:

ADD http://foo.com/bar.go /tmp/
复制代码

由于参数以尾部"/"结尾,因此Docker会从URL中推断出文件名并将其添加到指定的目录中。在这种情况下,一个名为/tmp/bar.go的文件将被添加到容器的文件系统中。

ADD的另一个功能是能够自动解压缩压缩文件。如果参数是一个识别压缩格式(tar,gzip,bzip2等)的本地文件,那么它将被解压到容器文件系统中的指定处。

ADD /foo.tar.gz /tmp/
复制代码

上面的命令会导致foo.tar.gz归档文件的内容被解压到容器的/ tmp目录中。 有趣的是,URL下载和解压功能不能一起使用。任何通过URL复制的压缩文件都不会自动解压缩。

魔法

显然,简单的ADD指令后面有很多功能。虽然这使得ADD非常灵活,但并没有使它具有特别的可预测性。以下是2013年12月针对ADD命令记录的问题的一段引文:

在我看来,当前的ADD指令非常的神奇。它可以添加本地和远程文件。它有时会解压一个文件,它有时不会解压文件。如果某个文件是要复制的tar包,则意外解压缩它。如果该文件是一个压缩格式的tar包,需要解压,则意外复制它。 - amluto

这个共识似乎是ADD试图做得太多而且让用户感到困惑。显然,没有人想要破坏与ADD现有用法的向后兼容性,所以决定添加一个更具可预测性的新指令。

类ADD,当更精简

当版本1.0的Docker发布时,包含了新的COPY指令。与ADD不同的是,COPY直接将文件和文件夹从构建上下文复制到容器中。

COPY不支持URL作为参数,因此它不能用于从远程位置下载文件。任何想要复制到容器中的东西都必须存在于本地构建上下文中。

另外,COPY对压缩文件没有特别的处理。如果您复制归档文件,它将完全按照出现在构建上下文中的方式落入容器中,而不会尝试解压缩它。

COPY实际上只是ADD的精简版本,旨在满足大部分“复制文件到容器”的使用案例而没有任何副作用。

使用哪个?

如果现在还不明显,Docker团队的建议是在几乎所有情况下都使用COPY。

真的,使用ADD的唯一原因是当你有一个压缩文件,你一定想自动解压到镜像中。理想情况下,ADD将被重新命名为EXTRACT之类的内容,以真正将这一点引入Docker生态(同样,出于向后兼容的原因,这不太可能发生)。 好的,但是从远程URL获取软件包的方法不是仍然有用吗?技术上,是的,但在大多数情况下,您可能会更好地运行curl或wget。考虑下面的例子:

ADD http://foo.com/package.tar.bz2 /tmp/
RUN tar -xjf /tmp/package.tar.bz2 \
  && make -C /tmp/package \
  && rm /tmp/package.tar.bz2
复制代码

这里我们有一条ADD指令,它从一个URL中检索一个包,然后是一条RUN指令,它将它解包,构建它,然后尝试清理下载的存档。

不幸的是,由于软件包检索和rm命令在单独的镜像层中,我们实际上并没有在最终镜像中节省任何空间(有关此现象的更详细的解释,请参阅我的优化docker镜像文章)。

在这种情况下,你最好像下面这样做:

RUN curl http://foo.com/package.tar.bz2 \
  | tar -xjC /tmp/package \
  && make -C /tmp/package

复制代码

这里我们使用curl命令下载压缩包,然后通过管道传递给tar命令解压。这样我们就不会在我们需要清理的文件系统上留下压缩文件。

将远程文件添加到镜像中可能仍有正当理由,但这应该是明确的决定,而不是您的默认选择。

最终,规则是这样的:使用COPY(除非你确定你需要ADD)。

原文地址:https://www.ctl.io/developers/blog/post/dockerfile-add-vs-copy/

标签:tmp,tar,URL,ADD,VS,指令,COPY
From: https://www.cnblogs.com/dirgo/p/16730218.html

相关文章

  • vscode 打包报错 error code ELIFECYCLE error This is probably not a problem wi
    执行命令:npmrunbuild详细报错信息:0infoitworkedifitendswithok1verbosecli[1verbosecli'C:\\ProgramFiles(x86)\\nodejs\\node.exe',1verbose......
  • texLive+VsCode
    首先进入镜像网站下载texLive卸载方式(C:/texlive/2022/tlpkg/pkg/installer/uninst.bat管理员身份运行)下载:运行驱动中的install-tl-windows.bat,可以修改安装位置,其他默......
  • 更便捷的VsCode
    所有都可以在设置中的键盘快捷方式查看查看->编辑器布局->拆分:可以同时对同一个文件进行编辑,用于文件较长不便查看时使用。同时对相同的名字更改多处位置:选中一......
  • R、01 VSCODE 配置 R 环境快速指南、4.2.1版本
    安装最新版R-4.2.1R:TheRProjectforStatisticalComputing(r-project.org)有大量镜像供选择下载,找中国地区镜像下载会快一点。安装一口气Next到底。https://cran......
  • kernel page address
    代码:#include<linux/module.h>#include<linux/init.h>#include<linux/moduleparam.h>#include<linux/gfp.h>#include<linux/mm.h>#include<linux/slab.h>#include<......
  • 实验2:Open vSwitch虚拟交换机实践
    实验2:OpenvSwitch虚拟交换机实践一、实验目的能够对OpenvSwitch进行基本操作;能够通过命令行终端使用OVS命令操作OpenvSwitch交换机,管理流表;能够通过Mininet的Pytho......
  • 实验2_Open vSwitch虚拟交换机实践
    一、实验目的能够对OpenvSwitch进行基本操作;能够通过命令行终端使用OVS命令操作OpenvSwitch交换机,管理流表;能够通过Mininet的Python代码运行OVS命令,控制网络拓扑中的Open......
  • 实验2:Open vSwitch虚拟交换机实践
    一、实验目的能够对OpenvSwitch进行基本操作;能够通过命令行终端使用OVS命令操作OpenvSwitch交换机,管理流表;能够通过Mininet的Python代码运行OVS命令,控制网络拓扑中的......
  • 实验2:Open vSwitch虚拟交换机实践
    (一)基本要求a)/home/用户名/学号/lab2/目录下执行ovs-vsctlshow命令、以及p0和p1连通性测试的执行结果截图;b)/home/用户名/学号/lab2/目录下开启MininetCLI并执行pi......
  • 实验2:Open vSwitch虚拟交换机实践
    三、实验报告3.1基础要求提交a)/home/用户名/学号/lab2/目录下执行ovs-vsctlshow命令、以及p0和p1连通性测试的执行结果截图;b)/home/用户名/学号/lab2/目录下开启M......