Docker build命令详解

Dockerfile创建完成后,可以使用docker build命令根据Dockerfile构建一个镜像。在上一关中,我们在Dockerfile所在的文件夹下执行docker build -t myimage .这条命令,然后镜像就被构建了。现在我们来详细地将这条命令。该docker build的命令格式如下:

docker build [OPTIONS] 上下文路径|URL

其中:

  • docker build: 用Dockerfile构建镜像的命令关键词;
  • -[OPTIONS]: 命令选项,常用的指令包括-t指定镜像的名字,-f显示指定Dockerfile,如果不使用-f,则默认将上下文路径下的名为Dockerfile的文件认为是构建镜像的“Dockerfile”;
  • 上下文路径|URL: 指定构建镜像的上下文的路径,构建镜像的过程中,可以且只可以引用上下文中的任何文件。

现在让我们在看看docker build -t myimage .这条命令,在这条命令中,使用-t指定了镜像名为myimage,由于没有使用-f指令,所以默认使用上下文路径下名为Dockerfile的文件认为是构建镜像的“Dockerfile”。最后指定上下文路径,在这条命令中,上下文路径是.
如果你学过Linux,你应该非常清楚上述命令中的小数点.代表的意思。在Linux中,小数点.代表着当前目录。所以docker build -t myimage .中小数点.其实就是将当前目录设置为上下文路径。

执行docker build后,会首先将上下文目录的所有文件都打包,然后传给Docker daemon,这样Docker daemon收到这个上下文包后,展开就会获得构建镜像所需的一切文件。
如下所示,在执行完docker build后,会首先sending build context to Deckor daemon,也就是将上下文目录下所有文件打包发给Docker daemon。所以在使用Dockerfile文件时构建镜像时,一般将它放在一个空文件夹下,就是为了防止将其他多余的文件传出去。然后依次执行Dockerfile的指令,如果指令正确执行,则继续执行下一条,直到所有指令执行正确完毕,镜像构建完成;如果指令执行出错,终止镜像构建。

[root@localhost newdir]# docker build -t myimage .
Sending build context to Docker daemon 2.048 kB
Step 1/2 : FROM ubuntu
 ---> 14f60031763d
Step 2/2 : RUN mkdir dir1
 ---> Running in c5117d908931
 ---> cb0193727724
Removing intermediate container c5117d908931
Successfully built cb0193727724

除了从本地构建以外,docker build还支持从URL构建,比如可以直接从Git repo中构建,这里也不展开介绍了,可以查看:
Docker官方文档

COPY指令和ADD指令

  • COPY复制文件;格式:COPY<源路径> <目标路径>;
    COPY指令编译到目录中的<源路径>的文件或目录复制到新的一层的内部的<目标路径>位置。<源路径>所指定的源必须在多个中,即必须是一部分根目录的相对路径!<目标路径>可以是容器内部的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用WORKDIR指令来指定,后面介绍)。目标路径不需要预先创建,如果目录不存在会在复制文件前先行创建目录。
  • ADD更高级的文件复制;格式:ADD<源路径> <目标路径>;
    ADD与COPY指令在功能上十分相似,但是在COPY的基础上增加了一些功能。例如,源路径可以是一个指向一个网络文件的URL,这种情况下,Docker引擎会试图下载这个URL指向的文件到<目标路径>去。

此外,当<源路径>为一个tar压缩文件时,该压缩文件在被复制到容器中时会被解压提取。但是使用COPY指令将将tar压缩文件复制到<目标路径>中。如下图所示:

[root@localhost tempdir]# docker build -t myimage .
Sending build context to Docker daemon  12.8 kB
Step 1/2 : FROM ubuntu
 ---> 14f60031763d
Step 2/2 : COPY ./hello.txt.tar /dir1/
 ---> 070559867e22
Removing intermediate container 1e55f9f19333
Successfully built 070559867e22
[root@localhost tempdir]# docker run myimage ls /dir1/
hello.txt.tar

而ADD指令如果<源路径>为一个tar压缩文件的话,ADD指令将会自动解压缩这个压缩文件到<目标路径>去。如下所示:

[root@localhost tempdir]# docker build -t myimage .
Sending build context to Docker daemon  12.8 kB
Step 1/2 : FROM ubuntu
 ---> 14f60031763d
Step 2/2 : ADD ./hello.txt.tar /dir1/
 ---> ead6431f75ba
Removing intermediate container f5fdcd97e196
Successfully built ead6431f75ba
[root@localhost tempdir]# docker run myimage ls /dir1/
hello.txt

这样,如果你只需要tar包中的文件内容而不需要tar包,不要先COPY ./hello.txt.tar.gz,然后RUN tar –xvf hello.txt.tar.gz && rm hello.txt.tar.gz。请直接使用ADD指令,ADD ./hello.txt.tar.gz

因为,这些的每一层重建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。诸如此类,删除前一层文件的操作,实际不是真的删除前一层的文件,,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但实际上该文件会一直跟随。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐