FROM
- FROM 指定基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。
- 格式:
FROM <基础镜像>
RUN
- RUN 指令是用来执行命令行命令的。
- 格式:
shell 格式:RUN <命令>
exec 格式: RUN ["可执行文件", "参数1", "参数2"]
- 每一个RUN 的行为:新建立一层,在其上执行这些命令,执行结束后, commit 这一层的修改,构成新的镜像,可使用
&&
将各个所需命令串联起来
COPY 复制文件
- COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。
- 格式:
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
- <源路径> 可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的filepath.Match 规则。
- <目标路径> 可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR 指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。
-
--chown=<user>:<group>
选项用来改变文件的所属用户及所属组。
注意:使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。
ADD 更高级的复制文件
- ADD 指令将从 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置,如果是压缩文件则自动解压。
- 格式:
ADD[--chown=<user>:<group>] <源路径>... <目标路径>
ADD[--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
- <源路径> 除了肯容易是构建上下文目录外,还可以是一个 URL 。
- <目标路径> 可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR 指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。
-
--chown=<user>:<group>
选项用来改变文件的所属用户及所属组。 - ADD 指令基本与 COPY 指令一样,但在COPY 指令基础上添加了以下功能:
a. <源路径> 可以是一个 URL ,这种情况下,Docker 引擎会试图去下载这个链接的文件放到 <目标路径> 去,下载后的文件权限自动设置为 600 。
b. 如果 <源路径> 为一个 tar 压缩文件的话,压缩格式为 gzip , bzip2 以及xz 的情况下, ADD 指令将会自动解压缩这个压缩文件到 <目标路径> 去。 - ADD 指令相对于 COPY 指令的劣势:
a. 如果自动设置的600权限并不是想要的权限,那么还需要增加额外的一层 RUN 进行权限调整。
b. 如果下载的是个压缩包,需要解压缩,也一样还需要额外的一层 RUN 指令进行解压缩。 - ADD 指令与 COPY 指令选择原则:
a. 所有的文件复制均使用 COPY 指令
b. 仅在需要自动解压缩的场合使用 ADD 指令
CMD 容器启动命令
- CMD 指令就是用于指定默认的容器主进程的启动命令的。
- 格式:
shell 格式: CMD <命令>
exec 格式: CMD ["可执行文件", "参数1", "参数2"...]
参数列表格式: CMD ["参数1", "参数2"...]
(在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数) - 在指令格式上,一般推荐使用 exec 格式,这类格式在解析时会被解析为 JSON数组,因此一定要使用双引号 " ,而不要使用单引号。
- 如果使用 shell 格式的话,实际的命令会被包装为 sh -c 的参数的形式进行执行。
CMD echo $HOME
将会被转换成CMD [ "sh", "-c", "echo $HOME" ]
- Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 systemd 去启动后台服务,容器内没有后台服务的概念。
- 对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。
- CMD 只可以出现一次,如果写了多个,只有最后一个生效。
ENTRYPOINT 入口点
- ENTRYPOINT 是在指定容器启动程序及参数。
- 格式:
shell 格式: ENTRYPOINT <命令>
exec 格式: ENTRYPOINT ["可执行文件", "参数1", "参数2"...]
- 当指定了 ENTRYPOINT 后, CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令
- ENTRYPOINT 指令比 CMD 指令更好的使用:
a. 让镜像变成像命令一样使用
b. 在应用运行前做准备工作 - ENTRYPOINT 只可以出现一次,如果写了多个,只有最后一个生效。
ENV 设置环境变量
- 设置环境变量,无论是后面的其它指令,如 RUN ,还是运行时的应用,都可以直接使用这里定义的环境变量。
- 格式有:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
- 通过环境变量,只需使用不同的环境变量即可让一份 Dockerfile 制作更多的镜像,升级镜像构建版本的时候,只需要更新相应环境变量即可, Dockerfile 构建维护变得更轻松了。
- 下列指令可以支持环境变量展开:
ADD 、 COPY 、 ENV 、 EXPOSE 、 LABEL 、 USER 、 WORKDIR 、 VOLUME 、STOPSIGNAL 、 ONBUILD 。
ARG 构建参数
- ARG 和 ENV 的效果一样,都是设置环境变量,但A RG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。
- 格式:
ARG <参数名>[=<默认值>]
- Dockerfile 中的 ARG 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 docker build 中用 --build-arg <参数名>=<值> 来覆盖。
VOLUME 定义匿名卷
- 容器运行时应该尽量保持容器存储层不发生写操作, VOLUME 可保证了容器存储层的无状态化。
- 格式:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
- 为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
EXPOSE 声明端口
- EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。
格式为 EXPOSE <端口1> [<端口2>...]
- Dockerfile 中写入这样的声明有两个好处:
a. 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;
b. 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
注意:EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
WORKDIR 指定工作目录
- WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在, WORKDIR 会帮你建立目录。
- 格式为
WORKDIR <工作目录路径>
USER 指定当前用户
- USER 改变之后层的执行 RUN , CMD 以及ENTRYPOINT 这类命令的身份。
- 格式:
USER <用户名>[:<用户组>]
- USER 只是帮助切换到指定用户,这个用户必须是事先建立好的,否则无法切换。
HEALTHCHECK 健康检查
- HEALTHCHECK 指令是告诉 Docker 应该如何进行判断容器的状态是否正常。
- 格式:
HEALTHCHECK [选项] CMD <命令>
:设置检查容器健康状况的命令, <命令> 分为shell 格式,和 exec 格式,命令的返回值决定了该次健康检查的成功与否: 0 :成功; 1 :失败; 2 :保留,不要使用这个值。
HEALTHCHECK NONE
:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令 - 通过该指令指定一行命令,用这行命令来判断容器主进程的服务状态是否还正常,从而比较真实的反应容器实际状态。
- 当在一个镜像指定了 HEALTHCHECK 指令后,用其启动容器,初始状态会为starting ,在 HEALTHCHECK 指令检查成功后变为 healthy ,如果连续一定次数失败,则会变为 unhealthy 。
- HEALTHCHECK 支持下列选项:
--interval=<间隔>
:两次健康检查的间隔,默认为 30 秒;
--timeout=<时长>
:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
--retries=<次数>
:当连续失败指定次数后,则将容器状态视为unhealthy ,默认 3 次。 - HEALTHCHECK 只可以出现一次,如果写了多个,只有最后一个生效。
ONBUILD 为他人做嫁衣裳
- 格式:
ONBUILD <其它指令>
- ONBUILD 后面跟的其它指令在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
- Dockerfile 中的其它指令都是为了定制当前镜像而准备的,唯有 ONBUILD 是为了帮助别人定制自己而准备的。