Wpz's Blog

闻道有先后,术业有专攻。

0%

Dockerfile 之 ADD/COPY 指令

Build Context(构建上下文)

在使用docker build命令通过Dockerfile创建镜像时,会产生一个build context(构建上下文)。所谓的构建上下文就是docker build命令的PATHURL指定的路径中的文件的集合。在镜像build过程中可以引用上下文中的任何文件,比如我们要介绍的ADDCOPY指令就可以引用上下文中的文件。

ADD

ADD指令用于将构建上下文中指定的文件添加到镜像中的,支持两种形式的写法:

ADD src dest
ADD ["src", "dest"]

ADD指令有以下几个特点:

1. 如果指定的 src 是归档文件(tar, zip, tgz, xz 等)会自动将其解压。
2. 如果指定的 src 是目录,只会添加目录中的内容而不包含目录自身。
3. 如果指定的 src 是 URL 地址,会从 URL 地址下载文件并将其添加到 dest,如果下载的文件是归档文件不会自动解压。

通过一个简单的栗子来说明

当前构建上下文目录结构:

root# tree
.
├── a
│   ├── a.log
│   └── b.log
├── alpine-minirootfs-3.9.3-x86_64.tar.gz
├── a.txt
└── Dockerfile

1 directory, 5 files
Dockerfile 文件
1
2
3
4
5
6
7
8
9
10
FROM scratch
WORKDIR /workspaces
# 添加归档文件到镜像中
ADD alpine-minirootfs-3.9.3-x86_64.tar.gz /
# 添加普通文件到镜像中
ADD a.txt .
# 添加目录到镜像中
ADD a .
# 从 URL 地址下载文件并添加到镜像中
ADD https://codeload.github.com/lz94wpz/lz94wpz.github.io/zip/master .

执行docker build -t alpine .构建镜像:

root# docker build -t alpine .
Sending build context to Docker daemon  2.689MB
Step 1/6 : FROM scratch
---> 
Step 2/6 : WORKDIR /workspaces
---> Running in 669cd08b2be7
Removing intermediate container 669cd08b2be7
---> 894324123641
Step 3/6 : ADD alpine-minirootfs-3.9.3-x86_64.tar.gz /
---> 471bc43f5e0c
Step 4/6 : ADD a.txt .
---> d22c05b89d9d
Step 5/6 : ADD a .
---> 54a77a7a1dd8
Step 6/6 : ADD https://codeload.github.com/lz94wpz/lz94wpz.github.io/zip/master .
Downloading    537kB
---> a443738c3f2f
Successfully built a443738c3f2f
Successfully tagged alpine:latest

Step 1/6获取空白镜像,Step 2/6指定镜像工作空间为/workspacesStep 3/6添加alpine-minirootfs-3.9.3-x86_64.tar.gz归档文件到镜像中,Step 4/6添加a.txt文件到镜像中,Step 5/6添加a目录到镜像中,Step 6/6下载归档文件并添加到镜像中。

执行docker run -it alpine /bin/sh启动容器:

root# docker run -it alpine /bin/sh
/workspaces # ls /
bin         etc         lib         mnt         proc        run         srv         tmp         var
dev         home        media       opt         root        sbin        sys         usr         workspaces
/workspaces # ls -l
total 708
-rw-r--r--    1 root     root             0 May 13 08:56 a.log
-rw-r--r--    1 root     root             0 May 13 08:55 a.txt
-rw-r--r--    1 root     root             0 May 13 08:56 b.log
-rw-------    1 root     root        721697 Jan  1  1970 master

可以看到alpine-minirootfs-3.9.3-x86_64.tar.gz文件添加到/根目录,由于是归档文件被自动解压了。a.txt文件添加到当前目录,也就是工作目录(/workspaces)。a目录中的内容添加到当前目录(只添加目录中的内容而不包含目录自身),https://codeload.github.com/lz94wpz/lz94wpz.github.io/zip/master下载的归档文件添加到当前目录,不会自动解压(URL下载和归档解包功能不能一起使用)。

解决添加目录,只添加目录中的内容而不包含目录自身的问题

上面的栗子可以看出,本意是要添加a目录到镜像中,结果只添加a目录下面的内容到镜像中。解决这个问题也很简单,稍微修改下Dockerfile文件:

1
ADD a .

改为:

1
ADD a ./a

解决从 URL 地址下载归档文件不自动解压的问题

解决从URL地址下载归档文件不自动解压的问题,思路也很简单,不自动解压那我们手动解压就是了:

1
2
ADD https://codeload.github.com/lz94wpz/lz94wpz.github.io/zip/master .
RUN unzip master && rm master

上面的方法虽然可行,但Docker官方不建议这么使用!Docker官方建议我们当需要从远程复制文件时,最好使用curlwget命令来代替ADD命令。原因是,当使用ADD命令时,会创建更多的镜像层,当然镜像的size也会更大。现在我们使用wget来替代上面的命令:

1
RUN wget https://codeload.github.com/lz94wpz/lz94wpz.github.io/zip/master && unzip master && rm master

COPY

COPY指令用于将构建上下文中指定的文件复制到镜像中的,同样支持两种形式的写法:

COPY src dest
COPY ["src", "dest"]

ADD不同的是COPY不会自动解压归档文件,也不支持URL作为src参数,因此不能用于从远程位置下载文件。COPY可以看做是ADD的精简版本。

使用 ADD 还是 COPY?

使用ADD还是COPYDocker团队的建议是在几乎所有情况下都使用COPY。唯一需要使用ADD的情况是需要自动解压归档文件。ADD通过URL下载文件则使用curlwget代替。

----------------本文结束感谢您的阅读----------------
复制本文地址随便逛逛听听小曲破坏小飞机简繁切换昼夜更替切换鼠标右键
主站网站导航Linux命令
开往虫洞跃迁