Dockerfile中的常用命令
Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。它们简化了从头到尾的流程并极大的简化了部署工作。Dockerfile从FROM命令开始,紧接着跟随者各种方法,命令和参数。其产出为一个新的可以用于创建容器的镜像。Dockerfile仅仅是构建docker images的源码。
注意:对于linux来讲,建议使用修改配置文件的方式,来修改应用配置。对于容器来讲,建议通过添加环境变量的方式,来修改设置。
注意:制作镜像有两种方式,基于镜像和基于Dockerfile。
Dockerfile中的格式
注释+指令(参数)
注意:指令本身不区分大小写。但是按照惯例,建议使用大写。
注意:Dockerfile是顺序执行的。
注意:第一个指令(非注释行),必须是"FROM",即基于哪个镜像制作新镜像。
注意:基于Dockerfile,不能使用其父目录中的内容,只能使用本目录和子目录的路径。
注意:.dockeringore文件,打包的时候,排除的目录。
注意:使用的命令都是容器中的命令。
注意:Dockerfile,第一个字母"D"大写。
注意:Dockerfile中的环境变量的格式
${variable:-word}
:给变量设默认值。引用的时候,如果该变量为空,则是用默认的。
${variable:+word}
:判断该变量是否为空,如果不为空,则使用默认值。反之为空。
Dockerfile中的指令:
FROM指令是最重要的一个且必须为Dockerfile文件开篇的第一个非注释行,用于为映像文件构建过程指定基准镜像,后续的指令运行于此基准镜像所提供的运行环境。**实践中,基准镜像可以是任何可用镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时,则会从Docker Hub Registry上拉取所需的镜像文件。如果找不到指定的镜像文件,docker build会返回一个错误信息。
- FROM:Dockerfile文件开头的第一行,基于哪个镜像制作新镜像;
FROM \<repository\>[:\<tag\>]
FROM \<repository\>@\<digest\>
注意:<repository>:指定作为base image的名称;
注意:<tag>:base image的标签,为可选项,省略时默认为latest;
注意:<digest>:hash码;
- MAINTANIER(depreacte):维护者(已经废弃)
用于让Dockerfile制作者提供本人的详细信息;Dockerfile并不限制MAINTAINER指令可在出现的位置,但推荐将其放置于FROM指令之后。可选项。已经被“LABLE”项替换。
MAINTAINER \<authtor's detail\>
示例:MAINTAINER “magedu <mage@magedu.com>”
注意:<author’s detail>可以是任何文本信息,但约定俗称的使用作者名称及邮件地址。
-
LABLE:用于为镜像添加元数据。
LABLE \<key\>=\<value\> \<key\>=\<value\> \<key\>=\<value\>
-
COPY:用于从Docker主机复制文件至创建的新映像文件。
COPY \<src\>...\<dest\>
COPY ["\<src\>",..."\<dest\>"]
示例:COPY index.html /data/web/html/
示例:COPY yum.repos.d /etc/yum.repos.d/
注意:<src>:要复制的源文件或目录,支持使用通配符。
注意:路径中如果有空白字符,通常使用第二种格式。
注意:<dest>:目标路径,即正在创建的image的文件系统路径;建议为<dest>使用绝对路径,否则,COPY指定则以WORKDIR为起始路径。
注意:<src>必须是build上下文中的路径,不能是其父目录的文件。
注意:如果<src>是目录,则其内部文件或子目录会被递归复制,但<src>目录自身不会被复制。
注意:<src>必须是build上下文中的路径,不能是其父目录中的文件。
注意:如果指定了多个<src>,或在<src>中使用了通配符,则<dest>必须是一个目录,且必须以"/"结尾。
注意:如果<dest>事先不存在,他将会被自动创建,这包括其父目录路径。
注意:Dockerfile,要惜字如金,每一条命令,都会生成一个新层。所以尽可能的将多个命令合并为单个层。
- ADD:ADD指令类似于COPY指令,ADD支持使用TAR文件和URL路径。
ADD \<src\> ... \<dest\>
ADD ["\<src\>",..."\<dest\>"]
注意:如果<src>为URL且<dest>不以/结尾,则<src>指定的文件将被下载并直接被创建为<dest>;如果<dest>以/结尾,则文件名URL指定的文件将被直接下载并保存为<dest>/<filename>;
注意:如果<src>是一个本地系统上的压缩格式的tar文件,他讲被展开为一个目录,其行为类似于"tar -x"命令;然而,通过URL获取到的tar文件将不会自动展开。
注意:如果<src>有多个,或其间接或直接使用了通配符,则<dest>必须是一个以/结尾的目录路径;如果</dest>不以/结尾,则其被视作一个普通文件,<src>的内容将被直接写入到<dest>;
- WORKDIR:用于指定为Dockerfile中所有的RUN、CMD、ENTERYPOINT、COPY和ADD指定设定工作目录;
WORKDIR \<dirpath\>
示例:WORKDIR /var/log
示例:WORKDIR $STATEPATH
注意:在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过,其是相对此前一个WORKDIR指令指定的路径。另外,WORKDIR也可调由ENV指定定义的变量。
- VOLUME:用于在image中创建一个挂载点目录,以挂载Docker host上的卷或其他容器上的卷。
VOLUME \<mountpoint\>
VOLUME ["\<mountpoint\>"]
注意:如果挂载点目录路径下此前有文件存在,docker run命令会在卷挂载完成后,将此前的所有文件复制到新挂在的卷中。
- EXPOSE:用于为容器打开指定要监听的端口以实现与外部通信。
EXPOSE \<port\>[/\<protocol\>] [\<port\>[/protocol] ... ]
示例:EXPOSE 11211/udp 11211/tcp
注意:<protocol>用于指定传输层协议,可为tcp或者udp,默认是TCP协议。
注意:EXPOSE指令可一次指定多个端口。
注意:EXPOSE指定了端口,启动容器的时候,并不一定会直接暴露,在启动容器的时候,需要“-P”参数,才可以。
- ENV:用于为镜像定义所需要的环境变量。并可被Dockerfile文件中位于其后的其他指令(如ENV、ADD、COPY等)所调用。调用格式:$viriable_name或${variable_name}
ENV \<key\> \<value\>
ENV \<key\>=\<value\> ...
注意:第一种格式中,<key>之后的所有内容均会被视作其<value>的组成部分,因此,一次只能设置一个变量;
注意:第二种格式可用一次设置多个变量,每个变量为一个"<key>=<value>“的键值对,如果<value>中包含空格,可以使用反斜线转义,也可以通过对<value>加引号进行标识;另外,反斜线也可以用于续行。
注意:定义多个变量时,建议使用第二种格式,方便在同一层中完成所有的功能。
注意:在Dockerfile中定义的环境变量,在启动容器时,无需指定变量,便自动创建。在运行容器时,通过”-e"参数,可以对他重新赋值。
- RUN:用于指定docker build过程中运行的程序,惬意是任何命令。
RUN \<command\>
RUN ["\<executable\>","\<param1\>","\<param2\>"]
示例:RUN rm -rf /tmp/pkgs
注意:第一种格式中,<command>通常是一个shell命令,且以“/bin/sh -c”来运行它,这意味着此进程在容器中的PID不为1,不能接受Unix信号,因此,当使用docker stop <container>命令停止容器时,此进程接收不到SIGTERM信号。并执行了exec命令,<command>进程的pid为1;
注意:第二种语法格式中的参数是一个JSON格式的数组,其中<executable>为要运行的命令,后面的<paramN>为传递给命令的选项或参数;然而,此格式指定的命令不会以"/bin/sh -c"来发起,即直接由内核创建进程,因此常见的shell操作,如变量替换、通配符将不会进行;不过,如果要运行的命令依赖于此shell特性的话,可以将其替换为类似下面的格式:RUN ["/bin/bash","-c","<executable>","<param1>"]
注意:RUN和CMD使用的时机不同,RUN是在docker build的时候使用的,CMD是在docker run的时候使用的。
注意:通配符、管道、输入、输出等操作,只有在shell下才可以使用。如果没有shell进程,便不可以直接使用了。
注意:exec命令,是使用子进程取代父进程的进程号。
- CMD:类似于RUN指令,CMD指令也可以用于运行任何命令或应用程序,不过,二者的运行时间点不同。RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像文件启动一个容器时。CMD指令的首要目的在于为启动容器指定默认要运行的程序,且运行结束后,容器也将终止;不过,CMD指令的命令可以被docker run的命令行选项所覆盖。在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效。
CMD \<command\>
CMD ["\<executable\>","\<param1\>","\<param2\>"]
CMD ["param1","param2"]
注意:前两种语法格式的意义同RUN;
注意:第三种则用于为ENTERPOINT指令提供默认参数;
- ENTRYPOINT:类似CMD指令的功能,用于为容器制定默认运行程序,从而使得容器像是一个单独的可执行程序。与CMD不同的是,有ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序。不过,docker run命令的–entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序。
ENTRYPOINT \<conmand\>
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。
- HEALTHCHECK:用于检查容器主进程健康与否。
参数:
–interval=DURATION(default:30s)
–timout=DURATION(default:30s)
–start-period=DURATION(default:0s)
–retries=N(default:3)
状态:
0:成功
1:不健康
2:预留状态
示例:HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1
-
SHELL:用于指定容器默认的shell类型。默认是“/bin/sh”;
-
STOPSIGNAL:不常用
-
ARG:只在build的时候,使用的参数。
注意:可以使用docker inspect查看ARG参数。
- ONBUILD:用于在Dockerfile中定义一个触发器。Dockerfile用于build映像文件,此影响文件亦可以作为base image被另一个Dockerfile用作FROM指令的参数,并以之构建新的映像文件。在后面的这个Dockerfile中的FROM指令在build过程中被执行时,将会触发创建其base image的Dockerfile文件中的ONBUILD指令定义的触发器。
ONBUILD \<INSTRUCTION\>
注意:尽管任何指令都可以注册成为触发器指令,但ONBUILD不能自我嵌套,且不会触发FROM和MAINTAINER指令。
注意:使用包含ONBUILD指令的Dockerfile构建的镜像应该使用特殊的标签,例如ruby:2.0-onbuild。
注意:在ONBUILD指令中,使用ADD或COPY指令应该格外的小心,因为构建过程的上下文在缺少指定的源文件是会失败。