Dockerfile:由一系列用于根据基础镜像构建新的镜像文件的专用指令序列组成;
指令:选定基础镜像、安装必要的程序、复制配置文件和数据文件、自动运行的服务以及要暴露的端口等;

命令:docker build;

语法:指令行、注释行和空白行;
指令行:由指令及指令参数构成;
指令:其字符不区分大小写;约定俗成,要使用全大写字符;
注释行:#开头的行,必须单独位于一行当中;

空白行:会被忽略;

Dockerfile指令:
FROM,MAINTAINER
COPY,ADD
WORKDIR, ENV 
USER
VOLUME
EXPOSE 
RUN 
CMD,ENTRYPOINT
ONBUILD

1、FROM

解释:FROM是Dockerfile里的第条指令(必须是),后面跟有效的镜像名(如果该镜像你的本地仓库没有则会从远程仓库Pull取)。然后后面的其它指令FROM的镜像中执行。

必须是第一个非注释行,用于指定所用到的基础镜像;

语法格式:
FROM  <image>[:<tag>] 或
FROM  <image>@<digest>

FROM  busybox:latest

FROM centos:6.9

注意:尽量不要在一个dockerfile文件中使用多个FROM指令;

2、MAINTAINER




格式:MAINTAINER <name>例如:MAINTANIER  MageEdu Linux Operation and Maintance Institute <mage@magedu.com>

解释:用于提供信息的指令,用于让作者提供本人的信息;不限制其出现的位置,但建议紧跟在FROM之后;

3、RUN

    用于指定docker build过程中要运行的命令,而不是docker run此dockerfile构建成的镜像时运行;

格式:RUN <command>或 RUN["executable", "param1", "param2"]。

解释:运行命令,命令较长使可以使用\来换行。推荐使用上面数组的格式    

语法格式:
	RUN  <command> 或
	RUN  ["<executeable>", "<param1>", "<param2>", ...]
	RUN ["/bin/bash", "-c", "<executeable>", "<param1>", "<param2>", ...]
	例如:RUN  yum  install  iproute nginx  && yum clean all



4、CMD



类似于RUN指令,用于运行程序;但二者运行的时间点不同;CMD在docker run时运行,而非docker build;


格式:CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;CMD ["param1","param2"] 为ENTRYPOINT指令指定的程序提供默认参数;

解释: 

CMD指定容器启动是执行的命令,每个Dockerfile只能有一条CMD命令,如果指定了多条,只有最后一条会被执行。如果你在启动容器的时候也指定的命令,那么会覆盖Dockerfile构建的镜像里面的CMD命令。

CMD指令的首要目的在于为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束;不过,CMD指令指定的程序可被docker run命令行参数中指定要运行的程序所覆盖

注意:如果dockerfile中存在多个CMD指令,仅最后一个生效;

CMD  ["/usr/sbin/httpd", "-c","/etc/httpd/conf/httpd.conf"]

5、ENTRYPOINT

格式: ENTRYPOINT ["executable", "param1","param2"] ENTRYPOINT command param1 param2(shell中执行)。例如:CMD ["-c"]  ENTRYPOINT  ["top", "-b"]

类似于CMD指令,但其不会被docker run的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给ENTRYPOINT指令指定的程序;但是,如果运行docker  run时使用了--entrypoint选项,此选项的参数可当作要运行的程序覆盖ENTRYPOINT指令指定的程序;

解释:和CMD类似都是配置容器启动后执行的命令,并且不可被 docker run每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。ENTRYPOINT没有CMD的可替换特性,也就是你启动容器的时候增加运行的命令不会覆盖ENTRYPOINT指定的命令。  

所以生产实践中我们可以同时使用ENTRYPOINT和CMD, 例如:




ENTRYPOINT ["/usr/bin/rethinkdb"]CMD ["--help"]

6、USER



指定运行镜像时,或运行Dockerfile文件中的任何RUN/CMD/ENTRYPOINT指令指定的程序时的用户名或UID;


格式:USER  <UID>|<Username>解释:指定运行容器时的用户名UID,后续的RUN指令也会使用这里指定的用户

注意:<UID>应该使用/etc/passwd文件存在的用户的UID,否则,docker run可能会出错;

7、EXPOSE



用于为容器指定要暴露的端口;


格式:EXPOSE<port> [<port>...]  <prot>为tcp或udp二者之一,默认为tcp;例如: EXPOSE  11211/tcp  11211/udp 解释:设置Docker容器内部暴露的端口号,如果需要外部访问,还需要启动容器时增加-p或者-P参数进行分配。

8、ENV



解释:设置环境变量,可以在RUN之前使用,然后RUN命令时调用,容器启动时这些环境变量都会被指定


定义环境变量,此些变量可被当前dockerfile文件中的其它指令所调用,调用格式为$variable_name或${variable_name};

ENV定义的环境变量在镜像运行的整个过程中一直存在,因此,可以使用inspect命令查看,甚至也可以在docker  run启动此镜像时,使用--env选项来修改指定变量的值;

格式:ENV<key> <value>  一次定义一个变量ENV <key>=<value> ...   一次可定义多个变量 ,如果<value>中有空白字符,要使用\字符进行转义或加引号;

ENV  myName="Obama Clark"   myDog=Hello\ Dog  \ myCat=Garfield

等同于:
ENV myName  Obama Clark
ENV myDog  Hello Dog 
ENV myCat  Garfield

解释:设置环境变量,可以在RUN之前使用,然后RUN命令时调用,容器启动时这些环境变量都会被指定

9、ADD:

    类似于COPY指令,额外还支持复制TAR文件,以及URL路径;




格式: ADD <src>... <dest>ADD ["<src>",... "<dest>"]解释:将指定的<src>复制到容器文件系统中的<dest> 所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0

如果文件是可识别的压缩格式,则docker会帮忙解压缩

示例: ADD  haproxy.cfg  /etc/haproxy/haproxy.cfg   ADD  logstash_*.cnf   /etc/logstash/ ADD   http://www.magedu.com/download/nginx/conf/nginx.conf   /etc/nginx/ 注意:以URL格式指定的源文件,下载完成后其目标文件的权限为600; 注意: <src>必须是build上下文中的路径,因此,不能使用类似“../some_dir/some_file”类的路径; 如果<src>是URL,且<dest>不以/结尾,则<src>指定的文件将被下载并直接被创建为<dest>;如果<dest>以/结尾,则URL指定的文件将被下载至<dest>中,并保留原名; 如果<src>是一个host本地的文件系统上的tar格式的文件,它将被展开为一个目录,其行为类似于tar  -x命令;但是,如果通过URL下载到的文件是tar格式的,是不会自动进行展开操作的; <src>如果是目录,递归复制会自动行;如果有多个<src>,包括在<src>上使用了通配符这种情形,此时<dest>必须是目录,而且必须得以/结尾; <dest>如果事先不存在,它将被自动创建,包括其父目录;

10、VOLUME



用于目标镜像文件中创建一个挂载点目录,用于挂载主机上的卷或其它容器的卷;


格式:VOLUME ["/data"]   VOLUME  ["<mountpoint>", ...]解释:可以将本地文件夹或者其他container的文件夹挂载到container中。

注意:如果mountpoint路径下事先有文件存在,docker run命令会在卷挂载完成后将此前的文件复制到新挂载的卷中;

11、WORKDIR



用于为Dockerfile中所有的RUN/CMD/ENTRYPOINT/COPY/ADD指令指定工作目录;


格式:WORKDIR/path/to/workdir解释:切换目录,为后续的RUNCMDENTRYPOINT 指令配置工作目录。 

可以多次切换(相当于cd命令), 

 也可以使用多个WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如



WORKDIR /aWORKDIR bWORKDIR cRUN pwd则最终路径为 /a/b/c。WORKDIR  /var/log WORKDIR  $STATEPATH

注意:WORDIR可出现多次,也可使用相对路径,此时表示相对于前一个WORKDIR指令指定的路径;WORKDIR还可以调用由ENV定义的环境变量的值;

12、ONBUILD  :定义触发器

ONBUILD

语法格式  ONBUILD  <INSTRUCTION>

例如:ONBUILD  ADD  my.cnf   /etc/mysql/my.cnf

当前dockerfile构建出的镜像被用作基础镜像去构建其它镜像时,ONBUILD指令指定的操作才会被执行;

注意:ONBUILD不能自我嵌套,且不会触发FROM和MAINTAINER指令;

13、ARG




格式:ARG<name>[=<default value>]解释:ARG指定了一个变量在docker build的时候使用,可以使用--build-arg <varname>=<value>来指定参数的值,不过如果构建的时候不指定就会报错。

14、COPY指令

用于从docker主机复制文件至正在创建的映像文件中;

语法格式:
COPY  <src> ...  <dest>
COPY  ["<src>",...  "<dest>"]  (文件名中有空白字符时使用此种格式)

<src>:要复制的源文件或目录,支持使用通配符;

dest>:目标路径,正在创建的镜像文件的文件系统路径;建立使用绝对路径,否则,则相对于WORKDIR而言;

                所有新复制生成的目录文件的UID和GID均为0;


例如:



COPY  server.xml  /etc/tomcat/server.xml



COPY  *.conf   /etc/httpd/conf.d/



注意:



<src>必须是build上下文中的路径,因此,不能使用类似“../some_dir/some_file”类的路径;


<src>如果是目录,递归复制会自动行;如果有多个<src>,包括在<src>上使用了通配符这种情形,此时<dest>必须是目录,而且必须得以/结尾;

<dest>如果事先不存在,它将被自动创建,包括其父目录;


示例1:

练习:
1)构建一个基于centos的httpd镜像,要求,其主目录路径为/web/htdocs,且主页存在,并以apache用户的身份运行,暴露80端口;
2)进一步地,其页面文件为主机上的卷;
3)进一步地,httpd支持解析php页面;
4)构建一个基于centos的maridb镜像,让容器间可互相通信;
5)在httpd上部署wordpress;

示例1:httpd
	
FROM centos:latest
MAINTAINER MageEdu "<mage@magedu.com>"

RUN sed -i -e 's@^mirrorlist.*repo=os.*$@baseurl=http://172.16.0.1/cobbler/ks_mirror/$releasever/@g' -e '/^mirrorlist.*repo=updates/a enabled=0' -e '/^mirrorlist.*repo=extras/a enabled=0' /etc/yum.repos.d/CentOS-Base.repo && \
	yum -y install httpd php php-mysql php-mbstring && \
	yum clean all && \
	echo -e '<?php\n\tphpinfo();\n?>' > /var/www/html/info.php

EXPOSE 80/tcp

CMD ["/usr/sbin/httpd","-f","/etc/httpd/conf/httpd.conf","-DFOREGROUND"]

示例2

FROM busybox:latest
MAINTAINER MageEdu <mage@magedu.com>

COPY index.html  /web/html/index.html

EXPOSE 80/tcp

CMD ["httpd","-f","-h","/web/html"]	

				
WORKDIR: /tmp/busybox-web
	index.html
	busybox-web.df
				
~]# docker build  -f  /tmp/busybox-web/busybox-web.cf  -t  busybox:web   /tmp/busybox 
~]# docker images