dockerfile指令
FROM
from 指令是最重要的一个且必须为Dockerfile文件开篇的第一个非注释行,用于为进项文件构建过程指定基础镜像,后续的指令运行与此基准镜像所提供的运行环境
实践中基准镜像可以是任何可用镜像文件,默认情况下docker bulid会在docker主机上查找指定的镜像文件,在其不存在时,则会从dockerHub Registry上去拉去,如果找不到指定的镜像文件,docker bulid会返回一个错误信息
语法:
FROM [--platform=<platform>] <image> [AS <name>]
or
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
or
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
FROM busybox:$VERSION
MAINTAINER
用于让Dockerfile制作者提供本人详细信息,dockerfile并不限制MAINTAINER指令可出现在什么位置,但是推荐将其放置于FROM指令之后
语法:
MAINTAINER <name>
COPY
用于用docker主机复制文件至创建的新镜像文件
语法:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
<src>: 要复制的源文件或者目录,支持使用通配符
<dest>: 目标路径,正在创建的image的文件系统路径,建议<dest>使用绝对路径否则copy指定则以workdir为起始路径
注意:
<src>必须是bulid上下文中的路径不能是其父目录的中的文件
如果<src>是目录,则其内部的文件或者是其子目录都会被递归复制,单<src>自身目录则不会被复制
如果制定了多个<src>,或者,<src>中使用了通配符,则<dest>必须是一个目录,必须一/结尾
如果<dest>事先不存在,它会被自动创建,这包括其父目录路径
文件:
COPY index.html /data/web/html/
目录:
COPY yum.repos.d /etc/yum.repos.d/
ADD
ADD指令类似于COPY指令,但是ADD指令支持使用TAR文件和URL路径
语法:
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
同COPY指令
如果<src>为URL切<dest>不以/结尾,则<src>指定的文件将被下载并直接创建<dest>,如果<dest>以/结尾则文件名URL指定的文件将被下载并保存为<dest><filename>
如果<src>是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于"tar -xf ",然而通过URL获取到的tar文件将不会自动展开
如果<src>有多个,或其间接或直接使用了通配符,则<dest>必须是一个以/结尾的目录路径,如果<dest>不以/结尾,则其被视作为一个普通文件,<src>的内容将会被直接写到<dest>
URL下载的tar文件解压:
ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/local/src/
本地系统tar解压:
ADD nginx-1.18.0.tar.gz /usr/local/src/
WORKDIR
用于为Dockerfile中所有的RUN,CMD,ENTRYPOINT,COPY和ADD指定设定工作目录
WORKDIR /path/to/workdir
在Dockerfile文件中WORKDIR指令可出现多次,其路径也可以为相对路径,不过其是相对于此前一个WORKDIR指令的路径
另外WORKDIR也可以调用ENV指定定义的变量
例子:
WORLDIR $STATEPATH
WORKDIR /usr/local/
ADD nginx-1.18.0.tar.gz ./src
VOLUME
用于在image中创建一个挂载点目录,已挂在docker host 上的卷或者其他容器上的卷
语法:
VOLUME ["/data"]
VOLUME /data
如果挂载点目录路径下此前文件名存在,在docker run命令会在挂载卷完成后将此前的所有文件复制到新挂载卷中
EXPOSE
用于为容器打开指定的要坚挺的端口已实现外部通信
语法:
EXPOSE <port> [<port>/<protocol>...]
<portocol> 用于指定传输层协议,可为tcp或者udp,默认为TCP协议
EXPOSE指令一次可指定多个端口
例:
EXPOSE 11234/udp 11234/tcp
EXPOSE 80
ENV
用于为镜像定义所需要的环境变量,并可被Dockerfile文件中位于其后的其他指令(如ENV,ADD,COPY等)所调用
调用格式:
$variable_name或者$(variable_name)
语法:
ENV <key> <value>
ENV <key>=<value> ...
第一种格式中,<key>之后的所有内容均会被视作其<value>的组成部分,因此一次只能设置一个变量
第二种格式可用一次设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果value中包含空格,可以以反斜线(\)进项转义,也可以通过对value加引号进行标识,另外反斜线也可用于续航
定义多个变量时建议是建议使用第二种方式,以便在同一层中完成所有功能
ENV DOCS_ROOT /data/web/html/
COPY index.html $DOCS_ROOT
或
ENV DOCS_ROOT=/data/web/html/ \ WEB_SERVER_PACKAGE="nginx-1.18.0"
COPY index.html ${DOCS_ROOT}
ADD ${WEB_SERVER_PACKAGE}.tar.gz ./src
RUN
用于定义docker build过程中运行的程序,其可使任何命令
语法:
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form)
第一个格式<command>通常是一个shell命令,且以"/bin/sh -c"来运行它,这意味着此进程在容器中的PID不为1,不能接受uinx信号,因此当时用docker stop <container>停止容器时此进程接收不到SIGTERM信号
第二种语法格式中的参数是一个json格式的数组,其中<executable>为要运行的命令,后面的<paramN>为传递给命令的选项或者参数,然而此种选项的命不会以"/bin/sh -c"来发起,因此常见的shell操作如变量替换以及通配符替换将不会进行,不过要运行的命令依赖于此shell特性的话可以将其替换为类似一下格式,
RUN ["/bin/bash", "-c", "executable","param1"]
CMD
类似于RUN指令,CMD指令也可以用于运行任何命令或应用程序,不过二者的运行时间点不同
RUN指令运行于镜像文件构建过程中,而CMD指令运行基于Dockerfile构建出的新镜像文件启动一个容器时
CMD指令的首要目的在于为启动容器指定默认要运行的程序,且其运行结束后,容器也将终止,不过CMD指令的命令起可以被docker run的命令选项进行覆盖
在Dockerfile中可以存在多个CMD指令,但尽最后一个生效
语法:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
前两种语法格式同RUN
第三种则用于为ENTRYPOINT指令提供默认参数
情况一:
Dockerfile中定义:
FROM busybox
MAINTAINER "xiaofang"
ENV WEB_DOCS_ROOT="/data/web/html/"
RUN mkdir -p ${WEB_DOCS_ROOT} && \
echo 'hello world' > ${WEB_DOCS_ROOT}/index.html
CMD /bin/httpd -f -h ${WEB_DOCS_ROOT}
使用以上这这种方式会以shell子进程方式运行
使用docker inspect httpd:v1.1查看镜像的CMD详细:
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"/bin/sh\" \"-c\" \"/bin/httpd -f -h ${WEB_DOCS_ROOT}\"]"
],
情况二:
FROM busybox
MAINTAINER "xiaofang"
ENV WEB_DOCS_ROOT="/data/web/html/"
RUN mkdir -p ${WEB_DOCS_ROOT} && \
echo 'hello world' > ${WEB_DOCS_ROOT}/index.html
CMD ["/bin/httpd","-f","-h ${WEB_DOCS_ROOT}"]
使用json数组的方式定义是不会以shell子进程的方式运行,通常这这种情况我们会以“/bin/sh -c”的方式进行运行
"Cmd": [
"/bin/httpd",
"-f",
"-h ${WEB_DOCS_ROOT}"
ENTRYPOINT
类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序
与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且这些命令行参数会被当做参数传递给ENTRYPOINT指定的程序
不过docker run命令的--entrypoint选项的参数可覆盖ENTRYPOINT指令的指定的程序
语法:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后做为其参数使用
dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅最后一个会生效
ENTRYPOINT /bin/httpd -f -h /data/web/html/
如果同时定义了CMD和ENTRYPOINT,CMD会被当做参数传给ENTRYPOINT
USER
用于指定运行image时的或运行dockerfile中任何RUN,CMD或,ENTRYPOINT指令的程序用户名或UID
默认情况下container的运行身份为root用户
语法:
USER <user>[:<group>]
or
USER <UID>[:<GID>]
需要注意的是<UID>可以为任意数字,但实践中其必须为/etc/passwd中某用户有效的UID否则docker run命令运行失败
HEALTHCHECK
HEALTHCHECK指令告诉 Docker 如何测试容器以检查它是否仍在工作。这可以检测诸如 Web 服务器陷入无限循环并且无法处理新连接的情况,即使服务器进程仍在运行。
当容器指定了健康检查时,除了其正常状态之外,它还具有健康状态。此状态最初为starting。每当健康检查通过时,它就会变成healthy(无论它之前处于什么状态)。连续失败一定次数后,变为unhealthy。
之前可以出现的选项CMD有:
--interval=DURATION(默认值:30s)
--timeout=DURATION(默认值:30s)
--start-period=DURATION(默认值:0s)
--retries=N(默认值:3)
运行状况检查将在容器启动后首先运行interval秒,然后在每次之前的检查完成后再次运行interval秒。
如果检查的单次运行时间超过timeout秒,则认为检查失败。
它需要重试连续的健康检查失败才能考虑容器unhealthy。
start period为需要时间引导的容器提供初始化时间。在此期间的探测失败将不计入最大重试次数。但是,如果在启动期间健康检查成功,则认为容器已启动,所有连续失败都将计入最大重试次数。
HEALTHCHECK一个 Dockerfile 中只能有一条指令。如果您列出多个,则只有最后一个HEALTHCHECK才会生效。
命令的退出状态指示容器的健康状态。可能的值为:
0:成功 - 容器运行良好,可以使用
1:不健康 - 容器不能正常工作
2:reserved - 不要使用这个退出代码
语法:
HEALTHCHECK [OPTIONS] CMD command (通过在容器内运行命令来检查容器健康状况)
HEALTHCHECK NONE (禁用从基础镜像继承的任何健康检查)
例:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
SHELL
该SHELL指令允许覆盖用于命令的shell形式的默认 shell 。Linux 上的默认 shell 是["/bin/sh", "-c"],Windows 上是["cmd", "/S", "/C"]. 该SHELL指令必须以 JSON 格式写入 Dockerfile。
该SHELL指令在 Windows 上特别有用,因为 Windows 有两种常用且截然不同的本机 shell:cmd和powershell,以及可用的备用 shell,包括sh.
语法:
SHELL ["executable", "parameters"]