Docker COPY: Dockerfile 最佳实践
Docker有两个类似的Dockerfile指令,COPY 和 ADD,它们都用于在镜像中导入文件,本文将解释为什么最好使用COPY而不是ADD,除非您想要将本地tar包自动提取到镜像中。使用 COPY 指令的最佳实践此 Dockerfile 指令将一个或多个本地文件或文件夹复制到目标的 docker 镜像中去。COPY <source>… <destin
Docker有两个类似的Dockerfile指令,COPY 和 ADD,它们都用于在镜像中导入文件,本文将解释为什么最好使用COPY而不是ADD,除非您想要将本地tar包自动提取到镜像中。
使用 COPY 指令的最佳实践
此 Dockerfile 指令将一个或多个本地文件或文件夹复制到目标的 docker 镜像中去。
- COPY <source>… <destination>
- COPY ["<source>",… “<destination>”] (此格式对于包含空格的路径是必需的)
举个例子在 Dockerfile 中使用 COPY 指令
这就是如何在 Dockerfile 中使用 COPY 指令构建一个 Ruby应用程序简单例子。
FROM ruby:2.5.1
WORKDIR /usr/src/app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
CMD ["./your-daemon-or-script.rb"]
它以 layers 为单位构建镜像,从父镜像 ruby:2.5.1 开始,使用 FROM 定义。
使用 WORKDIR 指令定义工作目录,接下来可以使用 COPY 或者 ADD 指令。
在这种情况下,使用copy时,它将从本地源复制文件。表示当前目录中的文件,到 WORKDIR 定义的位置。在上面的例子中,第二个COPY 指镜像中工作目录从当前目录拷贝。
使用 COPY 创建镜像 layers 的最佳实践
Docker 建议使用 COPY 创建镜像 layers,方法是在不同的 image layers 中保留不同的文件上下文。这意味着重建镜像是有效的。最不可能更改的文件应该在较低的 layers 中,而最可能更改的文件应该最后添加。
如果有多个dockerfile步骤使用来自不同文件的上下文,请分别复制它们,而不是一次全部复制。这样可以确保每个步骤的构建缓存只有在特定需要的文件发生更改时才失效。
–Best practices for writing Dockerfiles
这个原理在上面的dockerfile示例中得到了演示。通过复制 Gemfiles ,然后执行 Run bundle install,就可以使用安装的ruby gems创建一个image layer,可以对其进行缓存。最后两个docker指令将应用程序的文件复制到镜像中,并使用 CMD 设置默认命令。
这意味着,如果更改应用程序的任何文件,可以使用缓存的父层和中间层重新生成Docker镜像。这比从头开始构建所有这些模型要高效得多。
为什么你不应该使用 ADD 指令
ADD 指令的语法与 COPY 相似。除了将本地文件和目录复制到Docker镜像中的目的地之外,它还具有一些附加功能。
- ADD <source>… <destination>
- ADD ["<source>",… “<destination>”] (此格式对于包含空格的路径是必需的)
然而,Docker官方的Dockerfile最佳实践指南指出,在大多数情况下,COPY 是优于 ADD 的首选指令。
尽管 ADD 和 COPY 在功能上相似,但一般来说,还是首选 COPY。这是因为它比 ADD 更透明。COPY 仅支持将本地文件复制到容器中,而 ADD 具有一些不那么明显的功能(如本地tar提取和远程url支持)。因此,ADD 的最佳用途是将本地tar文件自动提取到镜像中,如 ADD rootfs.tar.xz/
-— Best practices for writing Dockerfiles
ADD 的一个另一个附加特性是它可以从URL复制文件,但Docker建议不要将其用于此目的。
从URL复制文件的最佳实践
如果 ADD 的源是一个url,它将下载文件并将其复制到docker镜像中的目的地。Docker认为,使用add从URL复制通常是不高效的,最好使用其他策略来包含所需的远程文件。
因为镜像大小很重要,所以强烈建议不要使用 ADD 从远程URL获取包;您应该使用curl或wget。这样,您就可以删除提取后不再需要的文件,而无需在镜像中添加其他层。
-— Dockerfile Best Practices
例如,您应该避免执行以下操作:
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all
相反,执行如下的操作:
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
你在何时应该使用 ADD 指令
如果 <source> 是一个可识别压缩格式的本地tar文件,那么它会自动作为目录解包到Docker镜像中。例如:add rootfs.tar.xz/。这是在docker官方建议使用的ADD的场景。
对其他文件或者目录,不需要ADD的自动解压能力的地方,你应该总是使用 COPY。
更多推荐
所有评论(0)