1 概述html
基于容器制做镜像的问题是,每次都要启动一个容器,在容器内部执行相关命令,才进行制做容器,这个比较麻烦。还有一种状况,多是制做后的容器,容器变得很庞大,用户拷贝也可能成问题,若是经过dockerfile,至关因而一个文档,客户能够基于dockerfile生成新的容器nginx
dockerfile仅仅是用来制做镜像的源码文件,是构建容器过程当中的指令,docker可以读取dockerfile的指定进行自动构建容器,基于dockerfile制做镜像,每个指令都会建立一个镜像层,即镜像都是多层叠加而成,所以,层越多,效率越低,建立镜像,层越少越好。所以能在一个指令完成的动做尽可能经过一个指令定义。docker
docker镜像制做的工做逻辑shell
首先须要有一个制做镜像的目录,该目录下有个文件,名称必须为Dockerfile,Dockerfile有指定的格式,#号开头为注释,,指定默认用大写字母来表示,以区分指令和参数,docker build读取Dockerfile是按顺序依次Dockerfile里的配置,且第一条非注释指令必须是FROM 开头,表示基于哪一个基础镜像来构建新镜像。能够根据已存在的任意镜像来制做新镜像。apache
Dockerfile可使用环境变量,用ENV来定义环境变量,变量名支持bash的变量替换,如${variable:-word},表示若是变量值存在,就使用原来的变量,变量为空时,就使用word的值做为变量的值,通常使用这个表示法。ubuntu
${variable:+word},表示若是变量存在了,不是空值,那么变量将会被赋予为word对应的值,若是变量为空,那么依旧是空值vim
.dcokerignore:把文件路径写入到.dockerignore,对应的路径将不会被打包到新镜像centos
FROM 数组
FROM指令是最重的一个且必须为 Dockerfile文件开篇的第一个非注释行,用于为映像文件构建过程指定基准镜像,后续的指令运行于此基准镜像所提供的运行环境 .缓存
实践中,基准镜像能够是任何可用镜像文件,默认状况下, docker build会在 docker主机上查找指定的镜像文件,在其不存在时,则会从 Docker Hub Registry上拉取所需的镜像文件 .若是找不到指定的镜像文件, docker build会返回一个错误信息
FROM 语法
FROM <repository>[:<tag>] 或者 FROM <repository>@<digest>
<repository>:指定做为base image的名称
<tag>:base image的标签,为可选项,省略时默认为 latest;
<digest>为校验码
MAINTANIER
用于让镜像制做者提供本人的详细信息
Dockerfile并不限制 MAINTAINER指令可在出现的位置,但推荐将
其放置于 FROM指令以后 .
语法:
MAINTAINER <authtor's detail> l <author's detail>但是任何文本信息,但约定俗成地使用做者名称及邮件地址,如
MAINTAINER "sunny <sunny@ghbsunny.cn>"
通常把MAINTAINER放在FROM后面
COPY
用于从 Docker主机复制文件至建立的新映像文件
语法
COPY <src> ... <dest>或 . COPY ["<src>",... "<dest>"]
<src>:要复制的源文件或目录,支持使用通配符
<dest>:目标路径,即正在建立的 image的文件系统路径;建议为 <dest>使用绝对路径,<dest>绝对路径为镜像中的路径,而不是宿主机的路径。不然, COPY指定则以 WORKDIR为其起始路径
注意:在路径中有空白字符时,一般使用第二种格式 .
文件复制准则
<src>必须是build上下文中的路径,即只能放在workshop这个工做目录下,不能是其父目录中的文件
若是<src>是目录,其内部文件或者子目录会被递归复制,但<src>目录自身不会被复制
若是指定了多个<src>,或在<src>中使用了通配符,则<dest>必须是一个目录,且dest目录必须以/结尾
若是<dest>事先不存在,它将会被自动建立,这包括其父目录路径
copy是指在当前的workshop工做目录中,准备好要添加到新镜像的文件放到这个workshop下面,copy过程实际是基于dockerfile在后台启动一个容器,把工做目录当作卷挂载到后台启动的容器,而后再把这些准备好的文件(workshop目录下)拷贝到后台容器,而后基于这个容器制做新镜像,因此,镜像的制做过程是基于指定的镜像来制做
例子
建立一个目录workshop,在该目录下新建index.html文件用于镜像制做的素材文件,在workshop下新建Dockerfile文件,把index.html拷贝到新镜像里
[root@docker ~]# mkdir workshop [root@docker ~]# cd workshop/ [root@docker workshop]# vim index.html [root@docker workshop]# vim Dockerfile FROM busybox:1.27.2 MAINTAINER "sunny <sunny@ghbsunny.cn>" COPY index.html /data/htdocs/ COPY yum.repos.d /etc/yum.repos.d/
Dockerfile制做完成后,用命令build制做基于dockerfile的新镜像。命令以下
[root@docker workshop]# docker build -t sunnydocker01:v1 ./
查看
docker images
查看到生成了一个新镜像sunnydocker01
启动新生成的镜像,在容器内部有目录/data/htdocs,而且有文件index.html,且成功拷贝/etc/yum.repos.d这个目录到新镜像中
[root@docker workshop]# docker run -it --rm --name sunny01 sunnydocker01:v1
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # ls data/htdocs/
index.html
/ # ls /etc/yum.repos.d/
CentOS-Base.repo docker-ce.repo epel.repo
bak/ epel-testing.repo sunny.repo
/ # ls /etc/yum.repos.d/
ADD
ADD指令相似于 COPY指令, ADD支持使用 TAR文件和 URL路径
语法
. ADD <src> ... <dest>或
. ADD ["<src>",... "<dest>"]
.操做准则 .
同COPY指令的4点准则
若是<src>为URL且<dest>不以/结尾,则<src>指定的文件将被下载并直接被建立为<dest>;若是<dest>以/结尾,则文件名URL指定的文件将被直接下载,并保存为<dest>/<filename>,注意,URL不能是ftp格式的url
若是<src>是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为相似于“tar -x”命令,而后,经过URL获取到的tar文件将不会自动展开
若是<src>有多个,或其间接或直接使用了通配符,则<dest>必须是一个以/结尾的目录路径;若是<dest>不以/结尾,则其被视做一个普通文件,<src>的内容将被直接写入到<dest>;
例子
在workshop目录下,准备了apache-tomcat-8.0.47.tar.gz 这个tar包,已经从网络上下载一个包,Dockerfile路径以下
[root@docker workshop]# vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
COPY index.html /data/htdocs/
COPY yum.repos.d /etc/yum.repos.d/
ADD http://nginx.org/download/nginx-1.14.0.tar.gz /tmp
ADD apache-tomcat-8.0.47.tar.gz /app/tomcat/
制做镜像
[root@docker workshop]# docker build -t test02:v1 ./
基于新镜像启动容器,并检查
[root@docker workshop]# docker run -it --rm --name testadd test02:v1
/ # ls
app bin data dev etc home proc root sys tmp usr var
/ # ls /tmp/
nginx-1.14.0.tar.gz
/ # ls /app/tomcat/
apache-tomcat-8.0.47
/ #
注意,此时url对应的nginx已经被下载到/tmp下,且这个nginx的tar包不会被展开,同时目录/app/tomcat/下有一个tomcat目录,为apache-tomcat-8.0.47.tar.gz 展开的目录
WORKDIR
workdir为工做目录,指当前容器环境的工做目录,用于为 Dockerfile中全部的 RUN、CMD、ENTRYPOINT、COPY和 ADD指定设定工做目录
语法
WORKDIR <dirpath>
在Dockerfile文件中, WORKDIR指令可出现屡次,其路径也能够为相对路径,不过,其是相对此前一个 WORKDIR指令指定的路径
另外, WORKDIR也可调用由 ENV指定定义的变量 .例如
WORKDIR /var/log
WORKDIR $STATEPATH
例子
指定workdir为/usr/local,至关因而容器启动后,会把工做目录切换到/usr/local这个workdir路径下,而不是默认的根目录,以下例子,则相对路径 ./src/ 的绝对路径为容器的/usr/local/src,制做镜像时,把nginx包拷贝到/usr/local/src,把tomcat包解压到/usr/local/src下面
[root@docker workshop]# vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
WORKDIR "/usr/local"
ADD http://nginx.org/download/nginx-1.14.0.tar.gz ./src/
ADD apache-tomcat-8.0.47.tar.gz ./
启动容器并检查
[root@docker workshop]# docker run -it --rm --name testworkdir testworkdir:v1
/usr/local # ls
apache-tomcat-8.0.47 src
/usr/local # ls src
nginx-1.14.0.tar.gz
/usr/local #
容器启动后,工做路径直接切换为/usr/local
VOLUME
定义卷,只能是docker管理的卷,,VOLUME为容器上的目录,用于在 image中建立一个挂载点目录,以挂载 Docker host上的卷或其它容器上的卷
语法
. VOLUME <mountpoint>或
. VOLUME ["<mountpoint>"]
若是挂载点目录路径下此前在文件存在, docker run命令会在卷挂载完成后将此前的全部文件复制到新挂载的卷中
例子
[root@docker workshop]# vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
VOLUME "/test/htdocs"
COPY index.html /test/htdocs/
制做镜像
[root@docker workshop]# docker build -t testvolume:v1
启动镜像
[root@docker workshop]# docker run -it --rm --name testvolume1 testvolume:v1
/ # ls
bin dev etc home proc root sys test tmp usr var
/ # ls /test/htdocs/
index.html
/ #
在另外的窗口检查该容器挂载的卷
[root@docker workshop]# docker inspect -f {{.Mounts}} testvolume1
[{volume e87fdd9ab3b8037167e23edb5c4eae3cc7c5d5ffa63c7a4fa4c18173e0e06460 /var/lib/docker/volumes/e87fdd9ab3b8037167e23edb5c4eae3cc7c5d5ffa63c7a4fa4c18173e0e06460/_data /test/htdocs local true }]
[root@docker workshop]# cd /var/lib/docker/volumes/e87fdd9ab3b8037167e23edb5c4eae3cc7c5d5ffa63c7a4fa4c18173e0e06460/_data
[root@docker _data]# ls
index.html
[root@docker _data]# cat index.html
hello,this is first container made by sunny~
[root@docker _data]#
EXPOSE
暴露指定端口,用于为容器打开指定要监听的端口以实现与外部通讯
语法
EXPOSE <port>[/<protocol>] [<port>[/<protocol>] ...] l
其中<protocol>用于指定传输层协议,可为 tcp或udp两者之一,默认为 TCP协议
EXPOSE指令可一次指定多个端口,可是不能指定暴露为宿主机的指定端口,由于指定的宿主机端口可能已经被占用,所以这里使用随机端口,例如
. EXPOSE 11211/udp 11211/tcp
例子
[root@docker workshop]# vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
VOLUME "/data/htdocs"
COPY index.html /data/htdocs/
EXPOSE 80/tcp
制做镜像
[root@docker workshop]# docker build -t testexpose:v1 ./
启动并暴露端口,注意,启动容器要跟大写P选项-P来暴露
[root@docker workshop]# docker run -it -P --rm --name testexpose testexpose:v1
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # ls data/htdocs/
index.html
/ #
在其余端口检查80口是否有暴露
[root@docker _data]# docker port testexpose
80/tcp -> 0.0.0.0:32768
[root@docker _data]#
ENV
ENV用于为镜像定义所需的环境变量,并可被 Dockerfile文件中位于其后的其它指令(如 ENV、ADD、COPY等)所调用 ,即先定义后调用
调用格式为 $variable_name或${variable_name}
语法
ENV <key> <value>或 . ENV <key>=<value> ... .
第一种格式中, <key>以后的全部内容均会被视做其 <value>的组成部分,所以一次只能设置一个变量
第二种格式,可用一次设置多个变量,每一个变量为一个“<key>=<value>”的键值对,若是<value>包含空格,能够以反斜线(\)进行转义,也可经过对<value>加引号进行标识;另外反斜线也能够用于续行;
.定义多个变量时,建议使用第二种方式,以便在同一层中完成全部功能
例子
下载一个nginx包,其中nginx的版本和nginx包的路径用变量替换
编辑Dockerfile
vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
ADD ${nginx_url} /usr/local/
建立镜像
[root@docker workshop]# docker build -t testenv:v1 ./
运行容器并验证
[root@docker workshop]# docker run -it --rm --name testenv testenv:v1
/ # ls /usr/local/
nginx-1.14.0.tar.gz
/ #
有些变量在运行为容器时依然有用,所以须要把那些变量在运行为容器时从新定义为一个新的值,若是变量不少,能够放到一个文件中进行定义,使用参数 --env-list实现,经过文件来加载环境变量
RUN
RUN用于指定 docker build过程当中运行的程序,其能够是任何命令,可是这里有个限定,通常为基础镜像能够运行的命令,如基础镜像为centos,安装软件命令为yum而不是ubuntu里的apt-get命令
RUN和CMD均可以改变容器运行的命令程序,可是运行的时间节点有区别,RUN表示在docker build运行的命令,而CMD是将镜像启动为容器运行的命令。由于一个容器正常只用来运行一个程序,所以CMD通常只有一条命令,若是CMD配置多个,则只有最后一条命令生效。而RUN能够有多个。
语法
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操做如变量替换以及通配符(?,*等)替换将不会进行,不过,若是要运行的没能力依赖此shell特性的话,能够将其替换为相似下面的格式
RUN ["/bin/bash","-C","<executable>","<paraml>"]
例子
把下载的nginx打包文件,用RUN命令来展开
编辑dockerfile
vim Dockerfile
FROM busybox:1.27.2
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
WORKDIR "/usr/local/src"
ADD ${nginx_url} /usr/local/src/
RUN tar xf nginx-${nginx_ver}.tar.gz
建立镜像
[root@docker workshop]# docker build -t testrun ./
运行容器并验证
[root@docker workshop]# docker run -it --rm --name testrun testrun:latest
/usr/local/src # ls
nginx-1.14.0 nginx-1.14.0.tar.gz
/usr/local/src #
若是RUN的命令不少,就用&&符号链接多个命令,少构建镜像层,提升容器的效率
例子以下
基础镜像为centos,RUN多个命令
因为安装是到互联网上的仓库进行安装,因此,建议把centos的yum源配置为本地,即建立镜像时,把yum的配置有本地仓库源配置在CentOS-Base.repo文件放在workshop下面,配置文件配置ADD拷贝一份到新建镜像的/etc/yum.repos.d目录下,由于常常默认会优先加载CentOS-Base.repo下的包,可是不建议使用这个方法,除非本地仓库有足够的包解决依赖关系,不然建议仅使用默认的便可
编辑dockerfile
[root@docker workshop]# vim Dockerfile
FROM centos:7.3.1611
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
WORKDIR "/usr/local/src"
ADD CentOS-Base.repo /etc/yum.repos.d/
ADD ${nginx_url} /usr/local/src/
RUN tar xf nginx-${nginx_ver}.tar.gz && yum -y install gcc pcre-devel openssl-devel make \
&& cd nginx-${nginx_ver} && ./configure && make && make install
建立镜像
[root@docker workshop]# docker build -t nginx:v1 ./
运行容器,启动nginx进程
[root@docker workshop]# docker build -t testexpose:v1 ./cc^C
[root@docker workshop]# docker run -it --rm --name nginxv1 nginx:v1
[root@ccedfdf5e63f src]# /usr/local/nginx/sbin/nginx
此时,nginx进程运行于后台,不建议这么作,由于容器的进程要运行于前台模式,不然容器会终止,nginx运行于前台,须要在nginx的配置文件nginx.conf里添加配置项
vi /usr/local/nginx/conf/nginx.conf
daemon off;
这样使得nginx运行于前台
再次运行nginx,则运行于前台
或者经过-g选项,在运行nginx的全局配置模式以后再运行某些参数,注意off后面的冒号
[root@ccedfdf5e63f local]# /usr/local/nginx/sbin/nginx -g "daemon off;"
CMD
相似于 RUN指令, CMD指令也可用于运行任何命令或应用程序,不过,两者的运行时间点不一样 . RUN指令运行于映像文件构建过程当中,而 CMD指令运行于基于 Dockerfile构建出的新映像文件启动一个容器时 . CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过, CMD指定的命令其能够被 docker run的命令行选项所覆盖 .在Dockerfile中能够存在多个 CMD指令,但仅最后一个会生效
语法
CMD <command>或
CMD ["<executable>","<param1>","<param2>"]或
CMD["<param1>","<param2>"]
.前两种语法格式的意义同 RUN
.第三种则用于为 ENTRYPOINT指令提供默认参数
例子
编译安装nginx,并将镜像的默认命令修改成nginx启动于前台,暴露80口
编辑dockerfile
vim Dockerfile
FROM centos:7.3.1611
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
WORKDIR "/usr/local/src"
EXPOSE 80/tcp
ADD ${nginx_url} /usr/local/src/RUN tar xf nginx-${nginx_ver}.tar.gz && yum -y install gcc pcre-devel openssl-devel make \
&& cd nginx-${nginx_ver} && ./configure && make && make install
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
制做镜像
[root@docker workshop]# docker build -t nginx:v3 ./
启动容器并测试
[root@docker workshop]# docker run -it --rm --name nginxv3 nginx:v3
测试,容器的ip 为 172.17.0.2,获得nginx的测试页
[root@docker yum.repos.d]# curl 172.17.0.2
查看容器80口被暴露为哪一个口
[root@docker yum.repos.d]# docker port nginxv3
80/tcp -> 0.0.0.0:32772
[root@docker yum.repos.d]# curl 10.10.10.72:32772
注意,CMD在dockerfile里写的命令,若是启动容器的命令行里执行命令,则会把dockerfile里的命令覆盖掉,以下,容器启动后,执行/bin/bash,而不是启动nginx于前台
[root@docker workshop]# docker run -it --rm -P --name nginxv3 nginx:v3 /bin/bash
[root@5f2f4b930df3 src]# ss -ntlp
若是dockerfile指定的CMD不容许覆盖,则使用ENTRYPOINT
ENTRYPOINT
相似 CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序
与CMD不一样的是,由 ENTRYPOINT启动的程序不会被 docker run命令行指定的参数所覆盖,并且,这些命令行参数会被看成参数传递给 ENTRYPOINT指定指定的程序 .不过, docker run命令的 --entrypoint选项的参数可覆盖 ENTRYPOINT指令指定的程序
语法
ENTRYPOINT <command>
ENTRYPOINT ["<excutable>","<param1>","<param2>"]
docker run 命令传入的命令参数会覆盖CMD指令的内容而且附加到ENTRYPOINT命令最后作为其参数使用 . Dockerfile文件中也能够存在多个 ENTRYPOINT指令,但仅有最后一个会生效
例子
把上例中的CMD执行命令,改为ENTRYPOINT
vim Dockerfile
FROM centos:7.3.1611
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
WORKDIR "/usr/local/src"
EXPOSE 80/tcp
ADD ${nginx_url} /usr/local/src/
RUN tar xf nginx-${nginx_ver}.tar.gz && yum -y install gcc pcre-devel openssl-devel make \
&& cd nginx-${nginx_ver} && ./configure && make && make install
ENTRYPOINT ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
制做镜像
[root@docker workshop]# docker build -t nginx:v5 ./
因为此次镜像修改相比上次不多,只差了一层CMD,构建过程直接使用缓存,因此速度很快,dockerfile里,建议CMD和ENTRYPOINT不用复用,两者选其一,除非明确指定CMD里的命令参数会被ENTRYPOINT当作参数执行
启动容器
run命令不带其余命令
[root@docker workshop]# docker run -it --rm -P --name nginxv3 nginx:v5
直接启动,能够正常启动nginx,并暴露端口
run命令修改默认命令如/bin/bash,与上例CMD不同,此时报选项错误,由于此时会把 /bin/bash当作参数传递给ENTRYPOINT指定的指令,此时ENTRYPOINT指定的指令为启动nginx,不能识别/bin/bash
[root@docker workshop]# docker run -it --rm -P --name nginxv3 nginx:v5 /bin/bash
nginx: invalid option: "/bin/bash"
[root@docker workshop]#
可是,若是必定要覆盖dockerfile里指定的ENTRYPOINT命令,那么在run命令使用参数--entrypoint来覆盖,以下
[root@docker workshop]# docker run -it --rm -P --name nginxv3 --entrypoint /bin/bash nginx:v5
[root@4c940d422f20 src]# pwd
/usr/local/src
[root@4c940d422f20 src]#
成功以进程/bin/bash启动了容器,覆盖了dockerfile里设定的nginx启动命令
USER
USER用于指定运行 image时的或运行 Dockerfile中任何 RUN、CMD或 ENTRYPOINT指令指定的程序时的用户名或 UID ,即改变容器中运行程序的身份
.默认状况下, container的运行身份为 root用户
语法
USER <UID>|<UserName>
须要注意的是, <UID>能够为任意数字,但实践中其必须为 /etc/passwd中某用户的有效 UID,不然, docker run命令将运行失败
ONBUILD
ONBUILD 用于在 Dockerfile中定义一个触发器 . 用来指定运行docker指令
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指令应该格外当心,由于新构建过程的上下文在缺乏指定的源文件时会失败
ONBUILD 在构建镜像时不会运行,是别人基于这个镜像做为基础镜像构建时,才会运行
以下例子
增长一个ONBUILD命令,执行RUN
FROM centos:7.3.1611
MAINTAINER "sunny <sunny@ghbsunny.cn>"
ENV nginx_ver=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz
WORKDIR "/usr/local/src"
EXPOSE 80/tcp
ADD ${nginx_url} /usr/local/src/
RUN tar xf nginx-${nginx_ver}.tar.gz && yum -y install gcc pcre-devel openssl-devel make \
&& cd nginx-${nginx_ver} && ./configure && make && make install
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
ONBUILD RUN echo -e "\nSunny do an onbuild~\n" >> /etc/issue
构建镜像
[root@docker workshop]# docker build -t nginx:v6 ./
基于nginx:v6启动容器,此时/etc/issue还没写入echo要插入的信息
[root@docker workshop]# docker run -it --rm -P --name nginxv3 nginx:v6 /bin/bash
[root@16e90f7a6460 src]# cat /etc/issue
\S
Kernel \r on an \m
[root@16e90f7a6460 src]#
而后基于这个nginx:v6镜像,再次制做一个新镜像,编辑一个新的Dockerfile
[root@docker ~]# mkdir nginxv7
[root@docker ~]# cd nginxv7/
[root@docker nginxv7]# vim Dockerfile
FROM nginx:v6
MAINTAINER "sunny <sunny@ghbsunny.cn>"
CMD "/bin/bash"
构建镜像,注意,会提示执行一个build trigger,以下Executing 1 build trigger
[root@docker nginxv7]# docker build -t nginx:v7 ./
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM nginx:v6
# Executing 1 build trigger
---> Running in 6bb18c52af99
Removing intermediate container 6bb18c52af99
基于新镜像nginx:v7启动新容器nginxv7
[root@docker nginxv7]# docker run -it --rm --name nginxv7 nginx:v7
[root@becc66948713 src]# cat /etc/issue
\S
Kernel \r on an \m
Sunny do an onbuild~
[root@becc66948713 src]#
此时,在旧的镜像中的dockerfile里的ONBUILD已经触发,把信息写入到/etc/issue里
LABEL
LABEL为磁盘映像文件添加元数据,能够基于这个LABEL调用这些元数据,一个LABEL就是一堆k/v值,一个镜像文件能够有多个LABEL