docker容器DockerFile篇

咱们前面的篇章讲过,咱们从docker hub或其余docker站点下载的镜像通常不会符合咱们的需求,因此咱们须要制做合适咱们自身的镜像,而制做镜像的方式有两种,一是基于现有的容器建立,二是基于DockerFile建立。
DockerFile是构建docker镜像的源码,是一个纯文本文件,以“#”号开头的是注释信息,剩下的为须要指定的命令,命令不区分大小写,可是建议使用大写,命令为顺序执行。但,第一个命令必须为‘FROM’开头,它表示制做该镜像必须以哪一个镜像为基础镜像。格式以下(在当前目录,cat Dockerfile):html

#test image
FROM nginx:1.10.2
ENV DOC_ROOT /usr/share/nginx/html/
LABEL "MAINTAINER"="lidf <lidf@wuaking.com>"
COPY index.html ${DOC_ROOT:-/usr/share/nginx/html/}
WORKDIR /data/nginx1/
ADD nginx-1.10.3.tar.gz ./
#ADD http://nginx.org/download/nginx-1.10.3.tar.gz /data/nginx2/
WORKDIR /data/nginx2/
COPY ps /bin/
COPY curl /bin/
COPY libprocps.so.4 /usr/local/lib/
COPY libcurl.so.4 /usr/local/lib/
COPY libssl3.so /usr/local/lib/
COPY libsmime3.so /usr/local/lib/
COPY libnss3.so /usr/local/lib/
COPY libnssutil3.so /usr/local/lib/
RUN ldconfig
#RUN mkdir -p /data/nginx3/ && tar -xf nginx-1.10.3.tar.gz -C /data/nginx3/
VOLUME /data/mysql/
EXPOSE 80/tcp
#CMD ["nginx","-g","daemon off;"]
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD touch /tmp1/aa || exit 1
CMD nginx -g "daemon off;"mysql


上面的示例文件中: 以"#"号打头的为注释信息,FROM通常为第一个指令,表示以什么镜像做为基础镜像linux


ENV
用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其余指令(如ENV、ADD、COPY等)所调用
调用格式为$variable_name或${variable_name}
语法
ENV <key> <value>或
ENV <key>=<value> ...
第一种格式中,<key>以后的全部内容均会被视做其<value>的组成部分,所以,一次只能设置一个变量
第二种格式可一次设置多个变量,每一个变量为一个"<key>=<value>"的键值对,若是<value>中包含空格,能够以反斜线\进行转义,有能够经过对<value>加引号进行标识;另外,反斜线也可用于续行;
定义多个变量时,建议使用第二种方式,以便在同一层中完成全部功能nginx


LABEL
用于添加描述镜像的元数据信息
语法:
LABEL <key>=<value> <key>=<value>
LABEL描述信息是键值对,若是须要在标签的值中包含空格,须要使用引号和反斜杠,一个镜像能够包含多个标签,多个标签能够在一行中指定web


COPY
用于从Docker宿主机复制文件到新建的镜像文件中
语法:
COPY <src>...<dest> 或
COPY ["<src>",... "<dest>"]
<src>:要复制的源文件或目录,支持通配符
<dest>:目标路径,即正在建立的image的文件系统路径;建议为<dest>使用绝对路径,不然,COPY指定则以WORKDIR为其其实路径;
注意:在路径中有空白字符时,一般使用第二种格式
文件复制准则
<src>必须是build上下文中的路径,不能是其父目录中的文件
若是<src>是目录,则其内部文件或子目录会被递归复制,但<src>目录自身不会被复制
若是指定了多个<src>,或在<src>中使用了通配符,则<dest>必须是一个目录,且必须以/结尾
若是<dest>实现不存在,他将会被自动建立,这包括其父目录路径sql


WORKDIR
用于为Dockerfile中全部的RUN、CMD、ENTRYPOINT\COPY和ADD设定工做目录
语法
WORKDIR <dirpath>
在Dockerfile文件中,WORKDIR指令可 出现屡次,其路径也能够为相对路径,不过,其是相对此前一个WORKDIR指令指定的相对路径
另外,WORKDIR也可调用有ENV指定定义的变量
例如
WORKDIR /var/log
WORKDIR $STATEPATHdocker


ADD
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>shell


VOLUME
用于在image中建立一个挂载点目录,以挂载Docker host上的卷或其余容器上的卷
语法:
VOLUME <mountpoint> 或
VOLUME ["<mountpoint>"]
若是挂载点目录路径下此前在文件存在文件,docker run命令会在卷挂载完成后将此前的全部的文件复制到新挂载的卷中json


EXPOSE
用于为容器打开指定要监听的端口以实现与外部通讯
语法
EXPOSE <port>[/<protocol>][<port>[/<protocol>]]
EXPOSE指令可一次指定多个端口,例如
EXPOSE 11211/udp 11211/tcp数组


RUN
用于指定docker build过程当中运行的程序,能够是任何命令,但必须是基础镜像中有的命令
语法
RUN <command> 或
RUN ["<executable>","<param1>","<param2>"]
第一种格式中,<command>一般是一个shell命令,且以"/bin/sh -c"来运行他,这意味着此进程在容器中的PID不为1,不能直接接受Unix信号,所以,当使用doker stop <container>命令来中止容器时,此进程接受不到SIGTERM信号;
第二种语法格式中的参数是一个JSON格式的数组,其中<executable>为要运行的命令,后面的<paramN>为传递给命令的选项或参数;然而,此种格式指定的命令不会以"/bin/sh -c"来发起,所以常见的shell操做如变量替换以及通配符替换\管道\输入输出重定向等shell的特性将不会进行;不过,若是要运行的命令依赖与此shell特性的话,能够将其替换为下面的格式。
RUN ["/bin/bash","-c","<executable>","<param1>"]
json数组中,要使用双引号


CMD
相似RUN指令,CMD指令也可用于运行任何命令或应用程序,不过两者的运行时间点不一样
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指令指定的程序
在Dockerfile中,若是同时出现CMD和ENTRYPOINT,则CMD后的指令会被当作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
healtcheck定义如何监测容器是否还在工做
他能够监测web服务的假死状态,好比已经访问不到服务了,可是web进程仍在运行
语法
HEALTHCHECK [OPTION] CMD command(在容器内部运行一共命令来检测)
HEALTHCHECK NONE(不作监控状态监测)
选项
--interval=DURATION(default:30s)
--timeout=DURATION(default:30s)
--start-period=DURATION(default:30s)#容器启动后多久开始执行健康状态监测
--retries=N(default:3)
执行命令有三种状态
0:成功
1:不健康
2:保留项(不要使用这个状态码)
例:
HEALTHCHECK --interval=5m --timeout=3s CMD cutl -f http://localhost/ || exit 1
docker inspect --format='{{json .State.Health}}' containerName 查看健康监测状态


SHELL
定义默认的shell
linux 默认shell为["/bin/sh","-c"],windowns为["cmd","/S","/C"]


了解了以上命令,就能够开始作镜像了,作镜像的命令为 docker build -t TagName ./


扩展:ENTRYPOINT实例

[root@localhost img3]# cat Dockerfile

FROM nginx:1.10.2
ENV DOC_ROOT="/data/web/html"
ADD entrypoint.sh /bin/
ADD index.html /data/web/html/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]

[root@localhost img3]# cat entrypoint.sh

#!/bin/shcat > /etc/nginx/conf.d/www.conf << EOFserver{server_name $HOSTNAME;listen ${IP:-0.0.0.0}:${PORT:-80} default;root ${DOC_ROOT:-/usr/share/nginx/html};}EOFexec "$@"以上两个文本展现了entrypoint的使用方式,首先咱们定义了entrypoint.sh这个脚本,这个脚本最关键的在最后一句,上面已经说过,在一个Dockerfile中,若是同时出现DENTRYPOINT和CMD,则CMD后的命令做为ENTRYPOINT的参数,在entrypoint.sh脚本中,最后一句exec表明使用后面的命令顶替当前的命令称为进程号为1的进程, $@ 就表明cmd后的全部参数.

相关文章
相关标签/搜索