一、Dockerfile
概述
A、Docker
制作镜像方式
- 基于容器制作镜像:
- 每次都需要启动容器,然后在容器内部执行相关命令,才能制作容器(比较麻烦)。
- 制作后的容器变得很庞大,用户拷贝也可能成为问题。
- 基于
Dockerfile
制作镜像:Dockerfile
是制作镜像的源码文件、是构建容器过程中的指令。Docker
能够读取Dockerfile
的指令进行自动构建容器。- 基于
Dockerfile
制作镜像,每一个指令都会创建一个镜像层(即镜像都是多层叠加而成)。 - 层越多、效率越低。创建镜像,层越少越好(能在一个指令完成的动作尽量通过一个指令)。
B、Docker
镜像制作过程
- 首先需要有一个制作镜像的目录,该目录下有个文件名称必须为
Dockerfile
。 docker build
读取Dockerfile
是按顺序依次读取Dockerfile
里的配置,且第一条非注释指令必须是FROM
开头,表示基于哪个基础镜像来构建新镜像。Dockerfile
有指定的格式:#
号开头为注释、指定默认用大写字母来表示以区分指令和参数。
二、Dockerfile
指令
组成部分 | 命令 |
---|---|
基础镜像信息 | FROM |
维护者信息 | MAINTAINER |
镜像操作指令 | RUN 、COPY 、ADD 、EXPOSE 、WORKDIR 、ONBUILD 、USER 、VOLUME 等 |
容器启动时执行指令 | CMD 、ENTRYPOINT |
A、FROM
FROM
指令是最重要一个且必须为Dockerfile
文件开篇的第一个非注释行。用于指定映像文件构建过程指定基准镜像,后续的指令运行于此基准镜像所提供的运行环境。- 基准镜像可以是任何可用镜像文件。
- 默认情况下,
docker build
会在Docker
主机上查找指定的镜像文件。当不存在时,则会从Docker Hub Registry
上拉取所需的镜像文件。如果找不到指定的镜像文件,docker build
会返回一个错误信息。 - 除了指定现有的基础镜像以外,还存在一个特殊的镜像
srcatch
,这个镜像是一个虚拟的概念,并不实际存在,它表示一个空白的镜像。如果以scratch
作为基础镜像,意味着将不使用任何镜像为基础,接下来你所写的指令将作为第一层开始存在。- 不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见。如
swarm
、coreos/etcd
。对Linux
下静态编译的程序来说,并不需要其他操作提供其运行时支持,所需的一切库都在可执行文件里了。因此使用scratch
作为基础,可以使镜像的体积更加小巧。
- 不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见。如
# <repository>:指定作为 base image 的名称
# <tag>:base image 的标签,为可选项,省略时默认为 latest
# <digest>:校验码
FROM <repository>[:<tag>]
FROM <repository>@<digest>
B、MAINTANIER
- 用于让镜像制作者提供本人的详细信息。
Dockerfile
并不限制MAINTAINER
指令可在出现的位置,但推荐放置于FROM
指令之后。
# 可以是任何文本信息,但约定俗成地使用作者名称及邮件地址
# MAINTAINER "hjyang <17826****@qq.com>
MAINTAINER <authtor's detail> l <author's detail>
C、COPY
- 从
Docker
宿主机复制文件至目标镜像的文件系统
# <src>:要复制的源文件或目录,支持使用通配符
# <dest>:目标路径,即正在创建的image的文件系统路径
# 建议为<dest>使用绝对路径(镜像中的路径)。否则COPY指令则以WORKDIR为其起始路径
COPY <src> ... <dest>
# 如果路径中有空格,建议使用该方式
COPY ["<src>",... "<dest>"]
COPY
准则:
<src>
必须是build上下文中的路径,不能是其父目录中的文件。- 如果
<src>
是目录,则再内部文件或者子目录会被递归复制,但是<src>
目录本身不被复制。 - 如果
<dest>
事先不存在,它会被自动创建,包括其父目录。但是它只是单纯的复制,并不会做文件提取和解压工作。 - 需要复制的目录一定要放在
Dockerfile
文件的同级目录下。
因为构建环境会上传到Docker
守护进程,而复制是在Docker
守护进程中进行的。任何位于构建环境之外的东西都是不可用的。COPY
指令的目的的位置则必须是容器内部的一个绝对路径。
示例:
创建一个目录/data/data/docker
,在该目录下新建index.html
文件用于镜像制作的素材文件,在/data/data/docker
下新建Dockerfile
文件,把index.html拷贝到新镜像里。
mkdir -p /data/data/docker
touch /data/data/docker/index.html
touch /data/data/docker/Dockerfile
Dockerfile
# 设置继承自哪个镜像
FROM ubuntu:14.04
# 下面是创建者的基本信息
MAINTAINER hjyang (17826xxxx@qq.com)
COPY index.html /data/html/
Dockerfile
制作完成后,用docker build
命令基于Dockerfile
制作新镜像
cd /data/data/docker
docker build -t copytest:v1 ./
docker images
基于新镜像启动容器,在容器内部有目录/data/html/
有文件index.html
docker run -it --rm --name copytest01 copytest:v1
ls /data/html/index.html
D、ADD
ADD
指令类似于COPY
指令,ADD
支持使用TAR文件
和URL路径
ADD <src> ... <dest> ADD ["<src>",... "<dest>"]
ADD操作准则:
- 如果
<src>
为URL
(不能是FTP
格式的URL
):<dest>
不以/
结尾,则<src>
指定的文件将被下载并直接被创建为<dest>
。<dest>
以/
结尾,则URL
指定的文件将被直接下载,并保存为<dest>/<filename>
。
- 如果
<src>
是宿主机上的压缩格式的tar文件
,它将被展开为一个目录。其行为类似于tar -x
命令(通过URL
获取到的tar文件
将不会自动展开)。 - 如果
<src>
有多个:或间接或直接使用了通配符,则<dest>
必须是一个以/
结尾的目录路径。如果<dest>
不以/
结尾,则其被视作一个普通文件,<src>
的内容将被直接写入到<dest>
。
示例:
创建一个目录/data/data/docker
,在该目录有apache-tomcat-8.5.45.tar.gz
mkdir -p /data/data/docker
touch /data/data/docker/index.html
touch /data/data/docker/Dockerfile
Dockerfile
# 设置继承自哪个镜像
FROM ubuntu:14.04
# 下面是创建者的基本信息
MAINTAINER hjyang (17826xxxx@qq.com)
COPY index.html /data/html/
ADD http://nginx.org/download/nginx-1.14.0.tar.gz /data/nginx/
ADD apache-tomcat-8.5.45.tar.gz /data/tomcat/
Dockerfile
制作完成后,用docker build
命令基于Dockerfile
制作新镜像
cd /data/data/docker
docker build -t addtest:v1 ./
docker images
基于新镜像启动容器,并检查
docker run -it --rm --name addtest01 addtest:v1
ls /data/nginx/
ls /data/tomcat/apache-tomcat-8.5.45/
注意:此时URL
对应的Nginx
已经被下载到/data/nginx/
下,且tar包
不会被展开。同时/data/tomcat/
目录下有个展开的目录。
E、WORKDIR
WORKDIR
为工作目录,指当前容器环境的工作目录。用于为Dockerfile
中所有的RUN
、CMD
、ENTRYPOINT
、COPY
、ADD
指定工作目录。- 在
Dockerfile
文件中,WORKDIR
指令可出现多次,其路径也可以为相对路径,不过相对此前一个WORKDIR
指令指定的路径。另外,WORKDIR
也可调用由ENV
指定定义的变量。
WORKDIR <dirpath>
示例一:
WORKDIR
使用绝对路径或相对路径
WORKDIR /a
WORKDIR b
WORKDIR c
# 执行结果 /a/b/c
RUN pwd
WORKDIR
也可以解析环境变量
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
# 执行结果 /path/$DIRNAME
RUN pwd
示例二:
指定WORKDIR
为/usr/local
,相当于是容器启动后,会把工作目录切换到/usr/local
下,而不是默认的根目录。如下例子:相对路径./src/
的绝对路径为容器的/usr/local/src
,制作镜像时Nginx
包拷贝到/usr/local/src
,把Tomcat
包解压到/usr/local/src
下。
Dockerfile
# 设置继承自哪个镜像
FROM ubuntu:14.04
# 下面是创建者的基本信息
MAINTAINER hjyang (17826xxxx@qq.com)
WORKDIR "/usr/local"
ADD http://nginx.org/download/nginx-1.14.0.tar.gz ./src/
ADD apache-tomcat-8.5.45.tar.gz ./
Dockerfile
制作完成后,用docker build
命令基于Dockerfile
制作新镜像
docker build -t workdirtest:v1 ./
docker images
基于新镜像启动容器,容器启动后工作路径直接切换为/usr/local
docker run -it --rm --name workdirtest workdirtest:v1
ls
ls ./src
F、VOLUME
VOLUME <mountpoint>
VOLUME ["<mountpoint>"]
- 定义卷:只能是
Docker
管理的卷。VOLUME
为容器上的目录,用于在image
中创建一个挂载点目录,以挂载Docker host
上的卷或其它容器上的卷。 - 如果挂载点目录路径下此前存在文件,
docker run
命令会在卷挂载完成后将此前的所有文件复制到新挂载的卷中。 - 实现挂载功能:可以将内地文件夹或者其他容器种得文件夹挂在到这个容器中。
VOLUME ["/data"]
:["/data"]
可以是JsonArray
,也可以是多个值。如下几种写法都是正确的:VOLUME ["/var/log/"] VOLUME /var/log VOLUME /var/log /var/db
- 使用场景为需要持久化存储数据。容器使用的是
AUFS
,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。
示例:
Dockerfile
# 设置继承自哪个镜像
FROM ubuntu:14.04
# 下面是创建者的基本信息
MAINTAINER hjyang (17826xxxx@qq.com)
VOLUME "/data/docker/volume"
COPY index.html /data/docker/volume/
Dockerfile
制作完成后,用docker build
命令基于Dockerfile
制作新镜像
docker build -t volumetest:v1 ./
docker images
基于新镜像启动容器:
docker run -it --rm --name volumetest volumetest:v1
ls /data/docker/volume/
查看容器挂载的卷:
docker inspect -f {{.Mounts}} volumetest
# 本地默认保存位置
cd /var/lib/docker/volumes/c4cb5b268ce41e48ccf366d7bf6f7c356e292703faf8adea980df3abc5358a6b/_data
G、EXPOSE
# <protocol>用于指定传输层协议(tcp或udp二者之一,默认为TCP协议)
EXPOSE <port>[/<protocol>] [<port>[/<protocol>] ...] l
- 暴露指定端口:用于为容器打开指定要监听的端口以实现与外部通信。
EXPOSE
指令可一次指定多个端口,但是不能指定暴露为宿主机的指定端口。因为指定的宿主机端口可能已经被占用,因此这里使用随机端口(EXPOSE 11211/udp 11211/tcp
)。EXPOSE
指令是声明运行时容器服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在Dockerfile
中这样声明有两个好处:- 一个是帮助镜像使用者更好的理解这个镜像服务的守护端口。
- 另一个作用则是在运行时使用随机端口映射时,也就是
docker run -p
命令时,会自动随机映射EXPOSE
端口。
- 要将
EXPOSE
和在运行时使用-p <宿主端口>:<容器端口>
区分开来:-p
是映射宿主端口和容器端口,就是将容器的对应端口服务公开给外界访问。EXPOSE
仅仅是声明端口使用什么端口而已,并不会自动在宿主进行端口映射。
示例:
Dockerfile
# 设置继承自哪个镜像
FROM ubuntu:14.04
# 下面是创建者的基本信息
MAINTAINER hjyang (17826xxxx@qq.com)
VOLUME "/data/docker/volume"
COPY index.html /data/docker/volume/
EXPOSE 80/tcp
Dockerfile
制作完成后,用docker build
命令基于Dockerfile
制作新镜像
docker build -t exposetest:v1 ./
docker images
基于新镜像启动容器(启动容器要跟选项-P
来暴露端口):
docker run -it -P --rm --name exposetest exposetest:v1
ls /data/docker/volume/
查看80端口
是否暴露
docker port exposetest
H、ENV
ENV
用于为镜像定义所需的环境变量,并可被Dockerfile
文件中位于其后的其它指令(如ENV
、ADD
、COPY
等)所调用 (即先定义后调用)。- 调用格式为
$variable_name
或${variable_name}
# <key>之后所有内容均会被视作其<value>的组成部分,因此一次只能设置一个变量
ENV <key> <value>
# 可用一次设置多个变量,每个变量为一个“<key>=<value>”的键值对。
# 如果<value>包含空格,以反斜线(\)进行转义,也可通过对<value>加引号进行标识,另外反斜线也可以用于续行。
# 定义多个变量时,建议使用第二种方式,以便在同一层中完成所有功能
ENV <key>=<value> ...
示例:
下载Nginx
包,其中Nginx
的版本和Nginx
包的路径用变量替换。
Dockerfile
# 设置继承自哪个镜像
FROM ubuntu:14.04
# 下面是创建者的基本信息
MAINTAINER hjyang (17826xxxx@qq.com)
ENV nginx_version=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_version}.tar.gz
ADD ${nginx_url} /data/nginx/
Dockerfile
制作完成后,用docker build
命令基于Dockerfile
制作新镜像
docker build -t envtest:v1 ./
docker images
基于新镜像启动容器:
docker run -it --rm --name envtest envtest:v1
ls /data/nginx/
I、RUN
RUN
用于指定docker build
过程中运行的程序,其可以是任何命令。但是有个限定,一般为基础镜像可以运行的命令,如基础镜像为CentOS
,安装软件命令为yum
而不是ubuntu
里的apt-get
命令。RUN
和CMD
都可以改变容器运行的命令程序,但是运行的时间节点有区别:RUN
表示在docker build
运行的命令。CMD
是将镜像启动为容器运行的命令。- 因为一个容器正常只用来运行一个程序,因此
CMD
一般只有一条命令。如果CMD
配置多个,则只有最后一条命令生效,而RUN
可以有多个。
- 如果
RUN
的命令很多,就用&&
符号连接多个命令,少构建镜像层,提高容器的效率。
# <command>通常是一个shell命令,且以“/bin/sh -c”作为父进程来运行它。
# 这意味着此进程在容器中的PID不为1,不能接收Unix信号。
# 因此:当使用docker stop <container>命令停止容器时,此进程接收不到SIGTERM信号。
RUN <command>
# 参数是一个JSON格式的数组,其中<executable>为要运行的命令,后面的<paramN>为传递给命令的选项或参数。
# 此种格式指定的命令不会以“/bin/sh -c”来发起,表示这种命令在容器中直接运行,不会作为shell的子进程。
# 因此:常见的shell操作如变量替换以及通配符(?,*等)替换将不会进行。
RUN ["<executable>", "<param1>", "<param2>"]
示例一:
下载Nginx
包,用RUN
命令来解压。
Dockerfile
# 设置继承自哪个镜像
FROM ubuntu:14.04
# 下面是创建者的基本信息
MAINTAINER hjyang (17826xxxx@qq.com)
ENV nginx_version=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_version}.tar.gz
ADD ${nginx_url} /data/nginx/
RUN tar -xf /data/nginx/nginx-${nginx_version}.tar.gz -C /data/nginx/
Dockerfile
制作完成后,用docker build
命令基于Dockerfile
制作新镜像
docker build -t runtest:v1 ./
docker images
基于新镜像启动容器:
docker run -it --rm --name runtest runtest:v1
ls /data/nginx/
J、CMD
- 类似于
RUN
指令,CMD
指令也可用于运行任何命令或应用程序,不过二者的运行时间点不同(见上面RUN
指令)。
# 语法格式的意义同 RUN
CMD <command>
# 语法格式的意义同 RUN
CMD ["<executable>","<param1>","<param2>"]
# 用于为ENTRYPOINT指令提供默认参数
CMD["<param1>","<param2>"]
示例一:
编译安装Nginx
,并将镜像的默认命令修改为Nginx
启动于前台,暴露80端口
Dockerfile
# 设置继承自哪个镜像
FROM centos:7.3.1611
# 下面是创建者的基本信息
MAINTAINER hjyang (17826xxxx@qq.com)
ENV nginx_version=1.14.0
ENV nginx_url=http://nginx.org/download/nginx-${nginx_version}.tar.gz
WORKDIR "/data/nginx/"
EXPOSE 80/tcp
ADD ${nginx_url} /data/nginx/
RUN tar xf nginx-${nginx_version}.tar.gz -C /data/nginx/ && yum -y install gcc pcre-devel openssl-devel make \
&& cd nginx-${nginx_version} && ./configure && make && make install
CMD ["/data/nginx/sbin/nginx","-g","daemon off;"]
Dockerfile
制作完成后,用docker build
命令基于Dockerfile
制作新镜像
docker build -t cmdtest:v1 ./
docker images
基于新镜像启动容器:
docker run -it --rm --name cmdtest cmdtest:v1
ls /data/nginx/
测试,容器的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
K、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
n
g
i
n
x
u
r
l
/
u
s
r
/
l
o
c
a
l
/
s
r
c
/
R
U
N
t
a
r
x
f
n
g
i
n
x
−
{nginx_url} /usr/local/src/ RUN tar xf nginx-
nginxurl/usr/local/src/RUNtarxfnginx−{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启动命令
L、USER
USER
用于指定运行image
时的或运行Dockerfile
中任何RUN
、CMD
或ENTRYPOINT
指令指定的程序时的用户名或UID
,即改变容器中运行程序的身份。- 默认情况下,
container
的运行身份为root
用户。
# <UID>可以为任意数字,但实践中其必须为/etc/passwd中某用户的有效UID,否则docker run命令将运行失败
USER <UID>|<UserName>
M、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
n
g
i
n
x
u
r
l
/
u
s
r
/
l
o
c
a
l
/
s
r
c
/
R
U
N
t
a
r
x
f
n
g
i
n
x
−
{nginx_url} /usr/local/src/ RUN tar xf nginx-
nginxurl/usr/local/src/RUNtarxfnginx−{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里
N、LABEL
LABEL
为磁盘映像文件添加元数据,可以基于这个LABEL
调用这些元数据,一个LABEL
就是一堆k/v
值,一个镜像文件可以有多个LABEL
。