![25f198bff60e42d1872796390302e9f7.png](https://i-blog.csdnimg.cn/blog_migrate/d0e70ffdf54cd5c413f3c5bfabd4bb22.jpeg)
此文仅作笔记使用,原文参考链接
Dockerfile有两个命令很相似:COPY和ADD,都是将上下文环境的文件夹或文件拷贝到镜像。
docker build的上下文环境是什么?
docker build -t image_name /a/b
docker build -t image_name .
docker build -t image_name url_path
最后一列就是这次镜像构建的上下文,即/a/b,.,url_path,所谓的上下文环境就是一个路径。默认docker 会在上下文的根目录下找 Dockerfile 文件,也可以通过参数指定Dockerfile文件。
相同点
1.如果要把本地的文件拷贝到镜像中,那么本地的文件必须是在上下文目录中的文件。docker 客户端会把上下文中的所有文件发送给 docker daemon。docker 客户端和 docker daemon 可以不在同一台机器上。如果我们在 Dockerfile 的 COPY 和 ADD 命令中引用了上下文中没有的文件,就会收到目录和文件找不到的错误。
不同点
除了不能用在 multistage 的场景下,ADD 命令可以完成 COPY 命令的所有功能,并且还可以完成两类超酷的功能:
- 解压压缩文件并把它们添加到镜像中
- 从 url 拷贝文件到镜像中
当然,这些功能也让 ADD 命令用起来复杂一些,不如 COPY 命令那么直观。
解压压缩文件并把它们添加到镜像中
如果我们有一个压缩文件包,并且需要把这个压缩包中的文件添加到镜像中。需不需要先解开压缩包然后执行 COPY 命令呢?当然不需要!我们可以通过 ADD 命令一次搞定:
WORKDIR /app ADD nickdir.tar.gz .
这应该是 ADD 命令的最佳使用场景了!
从 url 拷贝文件到镜像中
docker官方文档的最佳实践中却强烈建议不要这么用。
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
如果使用下面的命令,不仅镜像的层数减少,而且镜像中也不包含 big.tar.xz 文件:
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 命令!
加速镜像构建的技巧
在使用 COPY 和 ADD 命令时,我们可以通过一些技巧来加速镜像的 build 过程。比如把那些最不容易发生变化的文件的拷贝操作放在较低的镜像层中,这样在重新 build 镜像时就会使用前面 build 产生的缓存。比如笔者构建镜像时需要用到下面几个文件
![a3ce95f965890090f0a27c83e00b66f0.png](https://i-blog.csdnimg.cn/blog_migrate/3252100b58db565408a3e40f365f9fb0.png)
其中 myhc.py 文件不经常变化,而 checkmongo.py、checkmysql.py 和 checkredis.py 这三个文件则经常变化,那么我们可这样来设计 Dockerfile 文件:
WORKDIR /app
COPY myhc.py .
COPY check* ./
让 COPY myhc.py . 单独占据一个镜像层,当 build 过一次后,每次因 checkmongo.py、checkmysql.py 和 checkredis.py 这三个文件变化而导致的重新 build 都不会重新 build COPY myhc.py . 镜像层:
![88d7fff2bb11f9e642b09e803f9bb3f8.png](https://i-blog.csdnimg.cn/blog_migrate/41cb9abf0b7ac77738388b4626ef2fa7.jpeg)
如上图所示,第二步和第三步都没有重新 build 镜像层,而是使用了之前的缓存,从第四步才开始重新 build 了镜像层。当文件 size 比较大且文件的数量又比较多,尤其是需要执行安装等操作时,这样的设计对于 build 速度的提升还是很明显的。所以我们应该尽量选择能够使用缓存的 Dockerfile 写法。
链接
Dockerfile 中的 COPY 与 ADD 命令www.cnblogs.com![6f916ec6395a67964a5c3d4e6a809e30.png](https://i-blog.csdnimg.cn/blog_migrate/42d346bf7a277e2ccb2e1ddc6a640804.png)