Dockerfile语法解析

Dockfile介绍

      从上到下依次执行 每次执行一条指令就建立一个镜像层html

      第一条指令必须是FROM    表示须要构建的镜像是由哪一个镜像为基础镜像   后续的指令运行于此基准镜像所提供的运行环境 nginx

     能够设置 .dockeringore 指定不打包进镜像的文件列表web

     在docker build中执行的shell命令环境是由基础镜像所包含的命令集合docker

     ${ varriable:-default }  若是变量未设置值,则给变量赋一个默认值   ${ variable: +default } 若是已经给变量设置过值,则用default代替变量的值shell

 

   COPY指令数组

     从dockerfile的工做目录中 复制指定文件到目标镜像的文件系统中bash

     COPY <src> ... <dest> tcp

     COPY ["<src>",... "<dest>"] ide

     <dest>:目标路径,即正在建立的image的文件系统路径;建议为<dest>使用绝对路径   不然,COPY指定则以WORKDIR为其起始路径. ui

     注意:  在路径中有空白字符时,一般使用第二种格式 

     复制规则:

          src的路径不能是当前工做目录之上的目录或者文件 只能是工做目录中的文件或者子目录

          若是<src>是目录,则其内部文件或子目录会被递归复制,但<src>目录自身不会被复制  至关于shell中的 cp  -r  /root/dir/*    /tmp

          若是指定了多个<src>或在<src>中使用了通配符  则<dest>必须是一个目录,且必须以/结尾 

          若是<dest>事先不存在,它将会被自动建立,这包括其父目录路径

 

   ADD指令

        ADD指令相似于COPY指令    ADD支持使用TAR文件和URL路径 

        若是<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指定设定工做目录

    在Dockerfile文件中,WORKDIR指令可出现屡次,其路径也能够为相对路径,不过 ,其是相对此前一个WORKDIR指令指定的路径 

    另外 WORKDIR也可调用由ENV指定定义的变量 

 

VOLUME指令

    用于在image中建立一个挂载点目录   以挂载Docker host上的卷或 其它容器上的卷 

    VOLUME <mountpoint> 或   VOLUME ["<mountpoint>"] 

    若是挂载点目录路径下此前在文件存在,  docker run命令会在卷挂载完成后将此前的全部文件复制到新挂载的卷中

   不能指定宿主机上面的目录路径  只能建立docker manage volume

 

 EXPOSE指令

    用于为容器打开指定要监听的端口以实现与外部通讯   动态绑定到宿主机的随机端口  不能指定宿主机上的端口

    EXPOSE <port>[/<protocol>] [<port>[/<protocol>] ...]   EXPOSE指令可一次指定多个端口  EXPOSE 11211/udp 11211/tcp

    EXPOSE 只是表示当前镜像在运行为容器的时候能够暴露指定的端口,可是须要在run的时候配合 -P 选项 不然即便在Dockerfile中

    经过EXPOSE指定的端口在容器运行的时候默认仍是不会被暴露的   EXPOSE 必定须要配合 -P 选项 才能发挥做用

 

ENV指令

     用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其它指令(如ENV、ADD、COPY等)所调用

     ENV <key> <value> 

     ENV <key>=<value> ... 

     第二种格式可用一次设置多个变量,每一个变量为一个"<key>=<value>"的 键值对.若是<value>中包含空格,能够以反斜线(\)进行转义,也可经过对<value>加引号进行标识.另外,反斜线也可用于续行

    在docker run的时候能够经过 -e 选项直接覆盖Dockerfile文件中已经指定的ENV或者添加为容器新的ENV变量的

 

 RUN指令

    用于指定docker build过程当中运行的程序      其能够是任何命令  可是须要基础镜像的shell环境的支持

    能够出现屡次RUN指令

    RUN <command>       以shell的子进程运行

      <command>一般是一个shell命令,且以“/bin/sh -c”来运行它, 这意味着此进程在容器中的PID不为1,不能接收Unix信号.所以,当使用 docker stop <container>命令中止容器时,此进程接收不到SIGTERM信号;可以接收信号的进程通常是进程号为1的进程.

   RUN ["<executable>", "<param1>", "<param2>"]      直接由内核建立运行进程 可处理系统发送过来的信号 没法调用shell中的变量

     参数是一个JSON格式的数组,其中<executable>为要运行的 命令,后面的<paramN>为传递给命令的选项或参数;然而,此种格式指定的命令不会以“/bin/sh -c”来发起,所以常见的shell操做如变量替换以及通配符(?,* 等)替换将不会进行;不过,若是要运行的命令依赖于此shell特性的话,能够将其替换为相似下面的格式

   RUN ["/bin/bash", "-c", "<executable>", "<param1>"]

    

CMD指令    

    CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止. 不过CMD指定的命令其能够被docker run的命令行选项所覆盖 

    CMD命令的执行时间周期 就是容器的生命周期 CMD一旦执行完毕  容器就会当即中止  CMD指令只有最后一个指令生效

    CMD指令通常不会单独使用  一般都须要配合 ENTRYPOINT指令来设置

    CMD <command> 

    CMD [“<executable>”, “<param1>”, “<param2>”] 

    CMD ["<param1>","<param2>"]  为ENTRYPOINT指令提供默认参数

    当执行docker run的时候能够在最后添加自定义命令来覆盖CMD中指定的命令

   

ENTRYPOINT指令

     主要用来指定shell的  把shell做为容器中第一个启动进程 经过接收CMD命令 把命令做为参数启动指定的子进程

     用来指定容器内核启动的第一个进程 只有PID为1的进程才能接收系统发送给容器的系统信号

     由ENTRYPOINT启动的程序不会被docker run命 令行指定的参数所覆盖.并且,这些命令行参数会被看成参数传递给ENTRYPOINT指定指定的程序 

     不过,docker run命令的--entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序 

     docker run命令传入的命令参数会覆盖CMD指令的内容而且附加到 ENTRYPOINT命令最后作为其参数使用 

 

   一个容器只是为了运行单个程序

      每一个进程都应该是某个进程的子进程 除了init进程

     在shell中启动的任何进程都是shell的子进程 意味着若是shell退出那么在shell中启动的进程都会被终止掉

     一个运行nginx的容器中nginx进程号必须为1 不然因为容器中的nginx进程没法接收系统信号而没法stop和kill掉正在运行的容器

     exec 顶替shell进程PID为1 shell进程退出

 

USER指令

    用于指定运行image时的或运行Dockerfile中任何RUN、CMD或 ENTRYPOINT指令指定的程序时的用户名或UID 

    默认状况下container的运行身份为root用户 

    须要注意的是<UID>能够为任意数字 但实践中其必须为/etc/passwd中某用户的有效UID  不然docker run命令将运行失败

 

ONBUILD指令

    用于在Dockerfile中定义一个触发器 

    Dockerfile用于build映像文件,此映像文件亦可做为base image被另外一个Dockerfile用做FROM指令的参数,并以之构建新的映像文件

    在后面的这个Dockerfile中的FROM指令在build过程当中被执行时,将会“触发”建立其base image的Dockerfile文件中的ONBUILD指令定义的触发器 

 

HEALTHCHECK指令

     docker引擎断定容器是否健康的机制是仅仅断定容器是否处于运行状态

     断定运行的容器是否正常运行 并不能单一的检测容器是否正在运行 须要更加具体化 须要检测容器中的主进程是否能正常提供服务才行

     须要借助外部命令检测 如检测nginx容器是否正常  可使用命令请求主页 wget -O - -q a1f2903f6de3 获取返回结果 进行健康检查

   

ARG指令

   使用方法和ENV相同 可是只能在docker build执行指令的时候生效 不能在docker run中生效 ENV在两个执行阶段都有效果

   使用ARG指令能够用同一个Dockerfile 经过ARG的方式生成不一样版本的镜像   至关于给docker build命令传递变量参数

 

Dockerfile实例

[root@nginx-docker mynginx]# ls
Dockerfile  entrypoint.sh  index.html

[root@nginx-docker mynginx]# vi Dockerfile 

FROM nginx:1.14-alpine
LABEL maintainer="yxh"

RUN mkdir -p /data/web/html
ENV NGX_DOC_ROOT='/data/web/html/'
ADD entrypoint.sh /bin
ADD index.html ${NGX_DOC_ROOT}

EXPOSE 80 8080
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]



[root@nginx-docker mynginx]# vi entrypoint.sh 

#!/bin/sh

cat > /etc/nginx/conf.d/www.conf << EOF
server
{
   server_name $HOSTNAME;
   listen ${IP:-0.0.0.0}:${PORT:-80};
   root $NGX_DOC_ROOT;
}
EOF

exec "$@"


######调试容器##########
[root@nginx-docker mynginx]# docker run --name nginx1 -it nginx:1.14-alpine

nginx1默认启动的不是/bin/sh 因此即便使用-it 选项也没法进入容器
[root@nginx-docker mynginx]# docker run --name nginx1 -it nginx:1.14-alpine /bin/sh
/ # ifconfig
若是要进入交互式容器须要在最后添加启动命令 /bin/sh来覆盖CMD命令
这样就能够进入容器
/ # ps aux
PID   USER     TIME   COMMAND
    1 root       0:00 /bin/sh
    6 root       0:00 ps aux

调试容器步骤 不管什么容器均可以采起这种方式
  docker run --name myweb1 --rm -it myweb:v0.1-1 /bin/sh
  docker exec -it  myweb1 /bin/sh 进入已经运行的容器 

/usr/sbin # netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN

/data # wget -O - -q a1f2903f6de3
<h1> my nginx index page </h1>
/data #

有环境变量的最大好处在docker run的时候能够直接根据变量生成各类
应用程序的配置文件
定义应用程序的配置文件的时候就只须要调用变量名称便可
docker run -e "HOSTNAME=yxh" --name yxhweb myweb2:v1.1

/ # vi /etc/hosts
/ # wget -O - -q  yxh
<h1> my nginx index page </h1>
Dockerfile实例
相关文章
相关标签/搜索