构建镜像
最后更新于
这有帮助吗?
最后更新于
这有帮助吗?
Dockerfile 是一个文本文件,其中包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
定制镜像,那么一定是有一个镜像作为基础镜像,在其上进行定制。基础镜像是必须指定的。因此在一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。
在 上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如 、、、、、、 等;也有一些方便开发、构建、运行各种语言应用的镜像,如 、、、、 等。可以在其中寻找一个最符合我们最终目标的镜像为基础镜像进行定制。
如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像,如 、、、、 等,这些操作系统的软件库为我们提供了更广阔的扩展空间。
除了选择现有镜像为基础外,Docker 还存在一个特出的镜像,名为 scratch,这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。
如果你以 scratch 为基础镜像的话,意味着你不移任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
在 Dockerfile 文件所在目录执行:
从命令的输出结果中,我们可以清晰的看到镜像的构建过程。在 Step 2
中,如同我们之前所说的那样,RUN
指令启动了一个容器 9cdc27646c7b
,执行了所要求的命令,并最后提交了这一层 44aa4490ce2c
,随后删除了所用到的这个容器 9cdc27646c7b
里我们使用了 docker build
命令进行镜像构建。其格式为:
在这里我们指定了最终镜像的名称 -t nginx:v3
,构建成功后,我们可以像之前运行 nginx:v2
那样来运行这个镜像,其结果会和 nginx:v2
一样。
我们注意到docker build
命令最后有一个.
,.
通常是表示当前目录,而Dockerfile
就在当前目录,因此不少初学者会以为这个路径是在指 Dockerfile
所在的路径,实则不然,通过对应上面的命令格式,我们会发现,这是在指定上下文路径。
当构建的时候,用户会指定构建镜像上下文的路径,docker build
命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎,这样 Docker 引擎收到这个上下文包后,展开就会得到构建镜像所需的一切文件。
如果在 Dockerfile
中这么写:
这并不是复制执行docker build
命令所在目录下的package.json
,也不是Dockerfile
所在目录下的packag.json
,而是复制上下文目录下的package.json
。
因此,COPY
这类指令中的源文件的路径都是相对路径。这也是很多初学者为什么 COPY ../package.json /app
或者 COPY /opt/xxx /app
无法工作的原因,因为这些路径已经超出了上下文的范围,Docker 引擎无法获得这些位置的文件。
如果观察 docker build
输出,我们其实已经看到了这个发送上下文的过程。
在默认情况下,如果不额外指定 Dockerfile 的话,会将上下文目录下的名为 Dockerfile 的文件作为 Dockerfile。实际上 Dockerfile 的文件名也可以是任意名,并且并不要求必须位于上下文目录中,比如可以用-f ../Dockerfile.php
参数指定某个文件作为 Dockerfile
。