一、 书写规则
一份标志的Dockerfile文件中应包含指令、注释等内容,构建指令应使镜像尽量干净没有垃圾文件——基于其是Linux命令集,可以想象Dockerfile就是一份指定文件名指定文件格式内容的脚本:
1、自动化:Dockerfile全程无交互(不同于其他脚本可能还给选择让在终端做出选择),所以整个构建过程需要保证命令集能够一直持续不断执行下去。
2、顺序:Dockerfile构建过程默认就是之上而下,所以对其中的命令编写要考虑顺序问题。
3、清理:构建镜像的过程中会产生很多临时文件,对于这些临时文件需要通过在Dockerfile文件最后写上清理系统的命令处理。
4、易读:对于这个作为IT从业人员是基本的职业素养。
二、指令
1、FROM
FROM指令表示将来构建的镜像来自哪个镜像,也就是使用哪个镜像作为基础进行构建。其必须是这个Dockerfile第一句有效指令。
2、MAINTAINER
这条指令主要指定维护者信息,方便他人寻找作者。
3、RUN
RUN指令用来在Docker的编译环境中运行指定命令。其会在shell或者exec的环境下执行命令,具体格式如下:
exec:RUN ["程序名", "参数1", "参数2",……]
需要注意的是exec格式不会触发shell,所以其可以免除运行/bin/sh的开销在没有bash的镜像中执行同时可以避免错误的解析命令字符串。其也具有一定缺点就是如$HOME这样的环境变量无法使用。
4、ENV
ENV指令用来指定在执行docker run命令运行镜像时,自动设置的环境变量。这个环境变量可以在后续任何RUN指令中使用,并在容器运行时保持。而且可以通过docker run命令的-e参数来修改。
其指令语法为:ENV <key> <value>
5、COPY
这条指令用来将本地的文件或文件夹复制到镜像的指定路径下
6、ADD
该指令与COPY作用类似,但实现不同。ADD指令可以从一个URL地址上下载内容复制到容器的文件系统中,还可以两压缩打包格式的文件解压后复制到指定路径。
在相同的复制命令下,使用ADD构建镜像的大小比COPY构建的镜像要大,所以如果只是单纯的复制文件尽可能用COPY。
7、EXPOSE
这条指令用于标明这个镜像中应用将会侦听某个端口,并希望能将这个端口映射到主机的网络界面上。
8、CMD
CMD提供了容器默认的执行命令。Dockerfile只允许使用一次CMD指令,所以如果有多个CMD指令时只有最后一个指令生效(后面的指令会覆盖之前的所有指令)。一般来说这也是整个Dockerfile脚本的最后一条指令——当Dockerfile已经完成了所有环境的安装与配置,通过CMD指令来指示docker run命令运行镜像时要执行的命令。
需要注意的是,docker run 命令可以覆盖CMD命令。CMD与ENTRYPOINT的功能极为类似。区别在于:如果docker run 后面出现与CMD指定相同的命令,那么CMD会被覆盖;而ENTRYPOINT会把容器名后面的所有内容都当成参数传递给其他指定的命令(不会覆盖)。另外,CMD指令还可以单独作为ENTRYPOINT指令的可选参数,共同组合成一条完成的启动命令。
9、ENTRYPOINT
这个指定与CMD很相似,其相当于把镜像变成一个固定的命令工具,它一般是不可能通过docker run 来改变的,例如:
10、VOLUME
该指令用来向基于镜像创建的容器添加数据卷。数据卷可以在容器建共享和重用,且其修改是立即生效的。
11、USER
USER指定运行容器时的用户名或UID(默认为root)。该指令可以在docker run命令中通过-u选项来覆盖。其主要应用场景在于,当服务不再需要管理员权限时可以通过该命令指定运行用户。
12、WORKDIR
该指令指定RUN、CMD与ENTRYPOINT命令的工作目录。同时,可以通过docker run -w标志在运行时覆盖指令指定的目录。
13、ONBUILD
该指令为设置二次构建指令——指定在构建镜像时并不执行而是在它的子镜像中执行。
14、LABLE
该指令添加元数据到镜像。每一个标签会生成一个layer,所以经理使用一个LABLE标签。
15、ARG
该指令定义了一个变量,用户可以在构建时使用,效果同docker build --build-arg一样,可以在构建时设定参数,这个参数只会在构建时存在——其与ENV类似,不同的是ENV不会在镜像构建后消失而ARG会消失无效。
16、STOPSIGNAL
该指令允许用户定制化运行docker stop时的信号。
17、HEALTHCHECK
这是一个健康检查指令,用来检查将来容器启动运行时是否正常。
18、SHELL
在Docker构建过程中,Linux下默认会使用/bin/sh作为shell环境。但是有时需要在其他shell环境中执行RUN的内容,这就需要用SHELL指令提醒Docker更换shell环境。