docker(11)Dockerfile 中的COPY与ADD 命令「建议收藏」

docker(11)Dockerfile 中的COPY与ADD 命令「建议收藏」前言Dockerfile中提供了两个非常相似的命令COPY和ADD,本文尝试解释这两个命令的基本功能,以及其异同点,然后总结其各自适合的应用场景。Build上下文的概念在使用dock

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前言

Dockerfile 中提供了两个非常相似的命令 COPY 和 ADD,本文尝试解释这两个命令的基本功能,以及其异同点,然后总结其各自适合的应用场景。
 

Build 上下文的概念

在使用 docker build 命令通过 Dockerfile 创建镜像时,会产生一个 build 上下文(context)。所谓的 build 上下文就是 docker build 命令的 PATH 或 URL 指定的路径中的文件的集合。在镜像 build 过程中可以引用上下文中的任何文件,比如我们要介绍的 COPY 和 ADD 命令,就可以引用上下文中的文件。
默认情况下 docker build -t test1 . 命令中的 . 表示 build 上下文为当前目录。当然我们可以指定一个目录作为上下文,比如下面的命令:

docker build -t test1 /home/jkc

我们指定/home/jkc目录为build上下文,默认情况下 docker 会使用在上下文的根目录下找到的 Dockerfile 文件。
 

COPY 和 ADD 命令不能拷贝上下文之外的本地文件

对于 COPY 和 ADD 命令来说,如果要把本地的文件拷贝到镜像中,那么本地的文件必须是在上下文目录中的文件。其实这一点很好解释,因为在执行 build 命令时,docker 客户端会把上下文中的所有文件发送给 docker daemon。考虑 docker 客户端和 docker daemon 不在同一台机器上的情况,build 命令只能从上下文中获取文件。如果我们在 Dockerfile 的 COPY 和 ADD 命令中引用了上下文中没有的文件,就会收到类似下面的错误:
docker(11)Dockerfile 中的COPY与ADD 命令「建议收藏」
 

与 WORKDIR 协同工作

WORKDIR 命令为后续的 RUN、CMD、COPY、ADD 等命令配置工作目录。在设置了 WORKDIR 命令后,接下来的 COPY 和 ADD 命令中的相对路径就是相对于 WORKDIR 指定的路径。比如我们在 Dockerfile 中添加下面的命令:

WORKDIR /app
COPY test_1.py .

然后构建名称为 test1 的容器镜像,并运行一个容器查看文件路径:
docker(11)Dockerfile 中的COPY与ADD 命令「建议收藏」
test_1.py 文件就是被复制到了 WORKDIR /app 目录下。
 

COPY 命令的简单性

如果仅仅是把本地的文件拷贝到容器镜像中,COPY 命令是最合适不过的。其命令的格式为:
COPY <src> <dest>
除了指定完整的文件名外,COPY 命令还支持 Go 风格的通配符,比如:

COPY check* /testdir/           # 拷贝所有 check 开头的文件
COPY check?.log /testdir/       # ? 是单个字符的占位符,比如匹配文件 check1.log

对于目录而言,COPY 和 ADD 命令具有相同的特点:只复制目录中的内容而不包含目录自身。比如我们在 Dockerfile 中添加下面的命令:

WORKDIR /app
COPY jkcdir .

其中 jkcdir 目录的结构如下:

[root@jkc docker-run]# tree jkcdir/
jkcdir/
├── file1
└── file2

0 directories, 2 files
[root@jkc docker-run]# 

重新构建镜像 test2,运行一个容器并查看 /app 目录下的内容:

[root@jkc docker-run]# docker run --rm -it test2 /bin/bash
root@36f1e844f1e1:/app# ls
file1  file2
root@36f1e844f1e1:/app# 

这里只有 file1 和 file2,少了一层目录 jkcdir。如果想让 file1 和 file2 还保存在 jkcdir 目录中,需要在目标路径中指定这个目录的名称,比如:

WORKDIR /app
COPY jkcdir ./jkcdir

重新构建镜像 test3,运行一个容器并查看 /app 目录下的内容:

[root@jkc docker-run]# docker run --rm -it test3 /bin/bash
root@e85abbf41c1b:/app# ls
jkcdir
root@e85abbf41c1b:/app# cd jkcdir/
root@e85abbf41c1b:/app/jkcdir# ls
file1  file2

 

ADD 命令

ADD 命令的格式和 COPY 命令相同,也是:ADD <src> <dest>
除了不能用在 multistage 的场景下,ADD 命令可以完成 COPY 命令的所有功能,并且还可以完成两类超酷的功能:

  • 解压压缩文件并把它们添加到镜像中
  • 从 url 拷贝文件到镜像中
    当然,这些功能也让 ADD 命令用起来复杂一些,不如 COPY 命令那么直观。
     

解压压缩文件并把它们添加到镜像中

如果我们有一个压缩文件包,并且需要把这个压缩包中的文件添加到镜像中。需不需要先解开压缩包然后执行 COPY 命令呢?当然不需要!我们可以通过 ADD 命令一次搞定:

WORKDIR /app
ADD jkcdir.tar.gz 

这应该是 ADD 命令的最佳使用场景了!
 

从 url 拷贝文件到镜像中

这是一个更加酷炫的用法!但是在 docker 官方文档的最佳实践中却强烈建议不要这么用!!docker 官方建议我们当需要从远程复制文件时,最好使用 curl 或 wget 命令来代替 ADD 命令。原因是,当使用 ADD 命令时,会创建更多的镜像层,当然镜像的 size 也会更大(下面的两段代码来自 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 产生的缓存。
&nbsp

总结

当第一次看到 COPY 和 ADD 命令时不免让人感到疑惑。但分析之后大家会发现 COPY 命令是为最基本的用法设计的,概念清晰,操作简单。而 ADD 命令基本上是 COPY 命令的超集(除了 multistage 场景),可以实现一些方便、酷炫的拷贝操作。ADD 命令在增加了功能的同时也增加了使用它的复杂度,比如从 url 拷贝压缩文件时弊大于利。希望本文能够解去大家对 Dockerfile 中 COPY 和 ADD 命令的疑惑。
参考:< https://www.cnblogs.com/sparkdev/p/9573248.html>

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/165204.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 如何保证docker2375端口的安全

    如何保证docker2375端口的安全情景再现:之前有很多朋友提过,当使用docker-maven-plugin打包SpringBoot应用的Docker镜像时,服务器需要开放2375端口。由于开放了端口没有做任何安全保护,会引起安全漏洞,被人入侵、挖矿、CPU飙升这些情况都有发生,今天我们来聊聊如何解决这个问题。问题产生的原因首先我们要明白问题产生的原因,才能更好地解决问题!Docker为了实现集群管理,提供了远程管理的端口。DockerDaemon作为守护进程运行在后台,可以执行发送到管理端口上的Docker命令。当我们修改do

    2022年6月13日
    219
  • Docker安装配置教程[通俗易懂]

    Docker安装配置教程[通俗易懂]之前docker很久就写了笔记了。后面因为家里有事,耽搁了一年。现在把这部分笔记重新上传一下。大家看看。Docker要求:lunix内核,要求3.8以上centos7Docker是一个进程,一启动就两个进程,一个服务,一个守护进程。占用资源就非常少,启动速度非常快,1s。一台机器上vm,3到10个实例。docker100到10000。1.核心概念:1)镜像images,事先做好一…

    2022年10月10日
    2
  • docker(7)docker-compose容器集群编排「建议收藏」

    docker(7)docker-compose容器集群编排「建议收藏」前言实际工作中我们部署一个应用,一般不仅仅只有一个容器,可能会涉及到多个,比如用到数据库,中间件MQ,web前端和后端服务,等多个容器。我们如果一个个去启动应用,当项目非常多时,就很难记住了,所有

    2022年7月31日
    10
  • 群晖docker使用教程_docker的使用

    群晖docker使用教程_docker的使用概括Docker与传统虚拟机的区别与传统虚拟机的区别Docker的安装的安装Dockerdaemon,client,containerd镜像与容器操作容器运行配置Docker网络配置网络配置AlpineDockerImage制作自己的DockerImageDocker安全性问题安全性问题Dock

    2022年10月9日
    5
  • centos7.4安装docker_docker安装python库

    centos7.4安装docker_docker安装python库前言当我们在一台电脑上搭建了python3.6的环境,下次换台电脑,又得重新搭建一次,设置环境变量等操作。好不容易安装好,一会提示pip不是内部或外部命令,一会又提示pip:commandno

    2022年7月28日
    9
  • docker离线安装部署_ubuntu 离线安装docker

    docker离线安装部署_ubuntu 离线安装docker说明使用虚拟机真实模仿离线环境虚拟机系统为CentOS7正文下载Docker二进制文件(离线安装包):下载地址本文使用/x86_64/docker-17.12.1-ce.tgz,注意对应操作系统类型。通过FTP工具将docker-17.12.1-ce.tgz上传到服务器上解压安装包tarzxfdocker-17.12.1-ce.tgz将docker相关命令拷贝到/usr/bin,方便直接运行命令sudocpdocker/*/usr/bin/启动Docke

    2022年9月26日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号