在进行docker部署的时候,一般都逃不过要写Dockerfile的命运。
每次写dockerfile都是到处查资料,东拼西凑的写。今天就一文来梳理一下到底该如何编写Dockerfile。
首先需要搞清楚,Dockerfile的目的是什么? Dockerfile 是一个用来构建镜像的文本文件。也就是说在Dockerfile里添油加醋,可以自己定制一个镜像。那么这就需要一条条的指令来完成。
先来看一个例子:
FROM node:latest
MAINTAINER XXX
RUN rm -rf /app
RUN mkdir /app
WORKDIR /app
COPY package.json /app/
RUN mkdir public
WORKDIR public
RUN mkdir upload
WORKDIR /appRUN npm install
COPY . /app/
RUN npm run buildEXPOSE 5000
下面就结合例子所用的命令和一些其他命令来逐一地做讲解。
1.FROM:定制的镜像都是基于 FROM 的镜像,这里的node就是定制需要的基础镜像。后续的操作都是基于 node。
2.RUN:用于执行后面跟着的命令行命令。(注意这些命令标示都是需要全大写字母)这里的命令就和终端操作的 shell 命令一样。
3.COPY:复制指令,从上下文目录中复制文件或者目录到容器里指定路径。左侧为源文件路径,右侧为容器内的路径。注意:容器路径不用事先建好,路径不存在的话,会自动创建。
4.ADD 指令和 COPY 的使用格式和功能一致(官方推荐使用 COPY):
ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
5.CMD:类似于 RUN 指令,用于运行程序,但二者运行的时间点不同: CMD 是在docker run 时运行,而RUN 是在 docker build时执行。注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
6.ENTRYPOINT:类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
7.ENV:设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。相当于是一个Dockerfile中变量
来使用了。
8.ARG: 构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
9.VOLUME:定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。这避免重要的数据,因容器重启而丢失。
10.EXPOSE :声明端口。
11.WORKDIR:指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。以 && 符号连接命令,这样执行后,只会创建 1 层镜像。
12.MAINTAINER:指明维护者。
13.HEALTHCHECK:告诉Docker如何测试容器以检查它是否仍在工作,即健康检查。其中,一些选项的说明:
- --interval=DURATION (default: 30s):每隔多长时间探测一次,默认30秒
- -- timeout= DURATION (default: 30s):服务响应超时时长,默认30秒
- --start-period= DURATION (default: 0s):服务启动多久后开始探测,默认0秒
- --retries=N (default: 3):认为检测失败几次为宕机,默认3次
一些返回值的说明:
- 0:容器成功是健康的,随时可以使用
- 1:不健康的容器无法正常工作
- 2:保留不使用此退出代码
以上就是一些常见的用于构建镜像的指令。实际做项目过程中,还需要不断使用才能熟悉这些命令的用意。现在来总结一下
Dockerfile结构大致分为四个部分:(1)基础镜像信息(2)维护者信息(3)镜像操作指令 (4)容器启动时执行指
Dockerfile每行支持一条指令,每条指令可带多个参数,支持使用以#号开头的注释。
下面有一个很生动形象的图片对上面的指令进行一个概括性的解释:
如果对以上的命令有疑惑的朋友,欢迎留言。
参考文献: