Dockerfile说明(Dockerfile Instructions)
FROM 选取基础镜像
- FROM <repository>:<tag>
- FROM <repository>@HASDID #更安全
MAINTANIER 作者信息;建议使用LABEL
- MAINTANIER <author details>
LABEL 元数据
- LABEL <key>=<value> ...
COPY 复制docker主机上的文件到创建的新映像文件
- COPY <src> ... <dest>
- COPY ["<src>" ... "<dest>"] #路径中有空格使用
文本复制准则:
- <src>必须是build上下文中的路径,不能是其父目录中的文件
- 如果<src>是目录,则其内部的文件和目录都会被递归复制,但是<src>本身是不会被复制的
- 如果指定了多个<src>或者<src>中使用了通配符,则<dest>必须是一个目录,必须以/结尾
- 如果<dest>事先不存在,将会被自动创建,这包括其父目录路径
- <dest>建议使用绝对路径,COPY指定时以WORKDIR为起始路径
ADD 类似于COPY指令,ADD支持使用TAR文件和URL路径
- ADD <src> ... <dest>
- ADD ["<src>" ... "<dest>"]
操作准则:
- 同COPY
- 如果<src>为URL且<dest>不以/结尾,则<src>指定的文件将被下载并直接创建为<dest>;如果<dest>以/结尾,则文件名URL指定的文件将被直接下载并保存为<dest>/<filename>
- 如果<src>是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于“tar -x”命令;然而,通过URL上获取到的tar文件将不会被自动展开
- 如果<src>有多个,或其间接或者直接使用了通配符,则<dest>必须是一个以/结尾的目录路径;如果<dest>不以/结尾,则其被视作为一个普通文件,<src>内容将会被直接写入到<dest>
WORKDIR 用于为Dockerfile中所有的RUN CMD ENTRYPOINT COPY和ADD 指定工作目录
- WORKDIR <dirpath>
- 在Dockerfile中WORKDIR指令可出现多次,其路径也可以为相对路径, 不过,其是相对于前一个WORKDIR指令的路径
- 另外WORKDIR也可以调用由ENV指定定义的变量
VOLUME 用于在image中创建一个挂载点目录,以挂载Docker host上的卷或者其他容器上的卷
- VOLUME <mountpoint>
- VOLUME ["<mountpoint>"]
- 如果挂载点目录路径下此前在文件存在,docker run命令会在挂载完成后将此前的所有文件复制到新挂载的卷中
EXPOSE 用于为容器打开指定要监听的端口以实现与外部通信(并没有真实的暴露到外部网络,而是待暴露的端口,最终还是需要docker run -P 来对外暴露)
- EXPOSE <port>[/<protocol>] [<port>[/<protocol>] ...] # <protocol>用于指定传输层协议,可为udp或tcp二者之一,默认为TCP协议
- EXPOSE指令可一次指定多个端口,例如:
-
- EXPOSE 11211/udp 11221/tcp
-
ENV 用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其他指令(如ENV ADD COPY等)所调用,调用格式为$variable_name或${variable_name}
- ENV <key> <value>
- ENV <key>=<value> ...
- 第一种格式中,<key>之后的所有内容均会被是做<value>的组成部分,因此,一次只能设置一个变量
- 第二种格式可以一次设置多个变量,每个变量为一个“<key>=<value>”的键值对,如果<value>中包含空格,可以用反斜线\进行转义,也可通过对<value>加引号进行标识;另外反斜线也可用于续行
- 定义多个变量建议选第二种方式,以便在同一层中完成所有功能
- 这些ENV变量在ducker run调用镜像的时候也可以被调用,并且被赋值修改
RUN 用于指定docker build过程中运行的命令,其可以任何命令
- RUN <command>
- RUN ["<executable>","<param1>","<param2>"]
- 第一种格式中,<command>通常是一个shell命令,且以“/bin/sh -c” 来运行它,这意味着此进程在容器中的PID不为1,不能接收Unix信号,因此,当使用docker stop <container>命令停止容器时,此进程收不到SIGTERM信号
- 第二种格式中的参数时一个JSON格式的数组,<executable>为要运行的命令,后面的<paramN>为传递给命令的选项或参数;然而,此种格式的命令不会以“/bin/sh -c” 来发起,因此常见的shell操作如:变量替换以及通配符替换将不会进行;不过,如果要运行的命令依赖于此shell特性的话,可以将其替换为类似下面的格式
-
- RUN ["/bin/bash","-c","<executable>","<param1>" ] #执行的命令后的多个参数需要全部写在param1中并且使用引号引起来作为一个参数
-
CMD 类似于RUN命令,不过二者运行时间点不同,docker run时执行
RUN指令运行于映像文件构建过程中,而CMD命令运行于Dockerfile构建出镜像文件启动一个容器
CMD指令的首要目的在于为启动的容器指定默认要运行的程序,并且其运行结束后,容器将终止;不过CMD指定的命令可以被docker run命令行选项覆盖
在Dockerfile中方可以存在多个CMD 命令,但仅最后一个会生效
- CMD <command>
- CMD ["<executable>","<param1>","<param2>"]
- CMD ["<param1>","<param2>"]
- 前两种语法格式的意义同RUN
- 第三种语法用于给ENTRYPOINT指令提供默认参数
ENTRYPOINT 指定镜像默认入口命令
类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序
与CMD不同的是,由于ENTRYPOINT启动的程序不会被docker run命令执行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序
---不过,docker run命令的--entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序
- ENTRYPOINT <command>
- ENTRYPOINT ["<executable>","<param1>","<param2>"]
- docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后作为其参数使用
- Dockerfile文件中也可以存在多个ENTRYPOINT,但仅有最后一个会生效
USER 用于指定运行image时的或运行Dockerfile中任何RUN、CMD或ENTRYPOINT指令指定的程序时的用户名或UID
默认情况下,container的运行身份为root用户
- USER <UID>|<UserName>
- 需要注意的是,<UID>可以为任意数字,但实践中其必须为/etc/passwd中某用户的有效UID,否则,docker run命令将运行失败
HEALTHCHECK 配置所启动容器如何进行健康检查
- HEALTHCHECK [options] CMD command 根据所执行命令返回值是否为0来判断(0-成功;1-失败;2-无意义);CMD是固定格式,command才是需要执行的检查命令
-
- options支持的参数:
- --interval=DURATION (default:30s) 过多久检查一次
- --timeout=DURATION (default:30s) 每次检查等待结果的超时时间
- --start-period=DURATION (default:0s) docker run命令执行成功等待多久时间开始健康检查
- --retries=N (default:3s) 如果失败了,重复几次失败才最终确定结果
- options支持的参数:
-
- HEALTHCHECK NONE 禁止基础镜像中的健康检查
SHELL 指定其他命令使用shell时的默认shell类型
- SHELL ["executable","parameters"]
- 默认值为 [“/bin/sh”,"-c"]
ARG 定义创建镜像过程中使用的变量
- ARG <name>[=<default value>]
- 在执行docker build时,可以通过-build-arg <varname>=<value>来为变量赋值
- 当镜像编译成功后,ARG指定的变量将不再存在; ENV指定的变量将在镜像中保留
- Docker内置了一些镜像创建变量,用户无需声明可直接使用,包括(不区分大小写)HTTP_PROXY、HTTPS_PROXY、FTP_PROXY、NO_PROXY
ONBUILD 在Dockerfile中定义一个触发器,指定当基于所生成镜像创建子镜像时,自动执行的操作命令
- ONBUILD [INSTRUCTION]
例如: ONBUILD ADD . /app/src
- ONBUILD指令是隐式执行的,代码会在父镜像创建中注册完成,子镜像在基于父镜像(FROM xxx)创建新镜像的时候会自动触发执行
- 尽管任何指令都能被注册成为触发器,但ONBUILD不能自我嵌套,并且不会触发FROM和MAINTAINER指令
- 包含ONBUILD指令的Dockerfile创建的镜像应该使用特殊标签,例如nginx2.0-onbuild
- 使用ONBUILD ADD/COPY 等命令的时候需要考虑子镜像创建过程中对应的文件是否存在
STOPSIGNAL 指定所创建镜像启动的容器接收退出的信号值
- STOPSIGNAL signal