在前边的随笔中我们聊到了docker的基本命令,镜像,网络,存储卷以及基于现有容器制做docker镜像,相关随笔可参考https://www.cnblogs.com/qiuhom-1874/category/1766327.html;今天我们来聊一聊docker的另一个制作镜像的方式dockerfile;
什么是dockerfile?所谓dockerfile就是用来描述docker镜像制作过程的一指令文件;该文件是一个纯文本文件,docker Daemon 进程可以从该文件中读取指令,从而自动生成镜像;客户端可以使用docker bulid命令来指定dockerfile 所在目录,来生成以dockerfile里描述的镜像构建过程的镜像;
首先我们来了解下dockerfile的格式,dockerfile是一个纯文本文件,我们可以理解为构建镜像的源码;不同于其他编程语言,dockerfile里没有if else 没有循环,它里面仅仅有注释和构建镜像的指令;对于dockerfile注释就是以井号开头的行为注释,这个和shell和其他配置文件的语法一样;除此之外dockerfile里就只有指令了;严格的讲指令是不区分字符大小写的,通常我们约定俗成指令都是纯大写;除此之外在dockerfile的第一非注释行必须是FROM开头来明确的说明我们在基于那个镜像为基础镜像做镜像;
通常情况下dockerfile是放在一个目录下,该目录就是dockerfile的工作目录,我们在制作镜像所依赖的文件都必须放在该目录下,而dockerfile的名称也必须是Dockerfile(首字母大写,名称必须是Dockerfile),如果我们依赖的文件是一个目录下的部分文件,我们也可在dockerfile所在目录创建一个.dockerignore文件,把我们要忽略的文件名称写到里面即可,该文件支持通配符;
了解了上面的dockerfile的基本环境结构,接下来我们来说说dockerfile的指令的用法;
1、FROM:用于指定所创建镜像的基础镜像,如果本地不存在,默认会从dockerhub中下载;该指令是dockerfile里的第一个非注释行的指令;语法格式 FROM
2、MAINTAINER:用于指定维护者信息,dockerfile并不限制MAINTAINER指令可出现的位置,通常我们建议将该指令放在FROM之后;语法格式 MAINTAINER
示例:
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" [root@node1 test]#
提示:通常我们都不用MAINTAINER来指定作者信息,该指令几乎是废弃状态,建议使用LEBEL指令来指定;
3、LABEL:该指令用于指定添加镜像的元数据信息;语法格式为LABEL
示例:
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." [root@node1 test]#
提示:LABEL指令可以使用多次,用于添加更多的元数据信息;
4、COPY:该指令用于从Docker主机复制文件至创建的镜像文件中;语法格式 COPY
文件复制准则
1、
2、如果
3、如果指定了多个
4、如果
示例:
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." COPY html /var/www/html/ COPY test.html /tmp/ [root@node1 test]# tree . ├── Dockerfile ├── html │ ├── test1.html │ └── test2.html └── test.html 1 directory, 4 files [root@node1 test]#
测试:我们基于上面的Dockerfile构建镜像,看看构建好的镜像是否把对应文件都复制到对应目录下了?
[root@node1 test]# ls Dockerfile html test.html [root@node1 test]# pwd /root/test [root@node1 test]# docker build . -t myimg:v0.1 Sending build context to Docker daemon 5.632kB Step 1/6 : FROM busybox:latest latest: Pulling from library/busybox d9cbbca60e5f: Pull complete Digest: sha256:836945da1f3afe2cfff376d379852bbb82e0237cb2925d53a13f53d6e8a8c48c Status: Downloaded newer image for busybox:latest ---> 78096d0a5478 Step 2/6 : MAINTAINER "qiuhom" ---> Running in c311afd3d522 Removing intermediate container c311afd3d522 ---> bf9b966a914b Step 3/6 : LABEL version="1.0" ---> Running in 2ffb577afa08 Removing intermediate container 2ffb577afa08 ---> 5dd2e4b3f594 Step 4/6 : LABEL description="this is test file \ that label-values can span multiple lines." ---> Running in 489165bad668 Removing intermediate container 489165bad668 ---> 994f06ff65f8 Step 5/6 : COPY html /var/www/html/ ---> f2b46094d9a9 Step 6/6 : COPY test.html /tmp/ ---> c78c7188f804 Successfully built c78c7188f804 Successfully tagged myimg:v0.1 [root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v0.1 c78c7188f804 8 seconds ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]#
提示:可以看到docker在读dockerfile时会把一条指令启动一容器来执行,然后每一条指令都会构建成一层镜像;如果我们本地仓库中没有我们指定的基础镜像,它默认会从dockerhub仓库中去把指定镜像拖到本地;docker build命令是用来基于dockerfile来制作镜像的命令,其中-t表示指定我们生成的镜像的标签信息;
运行我们刚才制作好的镜像,看看我们的指定的目录和文件是否都复制到指定镜像中的目录中去了?
[root@node1 test]# docker run --name test --rm -it myimg:v0.1 /bin/sh / # ls bin dev etc home proc root sys tmp usr var / # ls /var/www/html/ test1.html test2.html / # ls /tmp/ test.html / # cat /var/www/html/test1.html this is test1 html / # cat /var/www/html/test2.html this is test2 html / # cat /tmp/test.html this is test dir html / # exit [root@node1 test]#
提示:可以看到我们以刚才制作的镜像运行成容器,容器对应目录有我们指定复制的文件;
5、ADD:该指令类似于COPY指令,ADD支持使用TAR文件和URL路径;语法格式 ADD
示例:
[root@node1 test]# ls Dockerfile html nginx-1.19.0.tar.gz test.html [root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." COPY html /var/www/html/ COPY test.html /tmp/ ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/src/ ADD nginx-1.19.0.tar.gz /tmp/ [root@node1 test]#
提示:以上Dokcerfile里指定把当前目录下的nginx-1.19.0.tar.gz 添加到镜像中的/tmp/下,并且会把nginx-1.19.0.tar.gz展开成一个目录;而对于
ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/src/这条指令它会把指定url的文件下载到/usr/src/,但是不会tar文件展开;
测试:把上面dockerfile编译成镜像,看看对应目录中的文件是否都展开了?
[root@node1 test]# docker build . -t myimg:v0.2 Sending build context to Docker daemon 1.05MB Step 1/8 : FROM busybox:latest ---> 78096d0a5478 Step 2/8 : MAINTAINER "qiuhom" ---> Using cache ---> bf9b966a914b Step 3/8 : LABEL version="1.0" ---> Using cache ---> 5dd2e4b3f594 Step 4/8 : LABEL description="this is test file \ that label-values can span multiple lines." ---> Using cache ---> 994f06ff65f8 Step 5/8 : COPY html /var/www/html/ ---> Using cache ---> f2b46094d9a9 Step 6/8 : COPY test.html /tmp/ ---> Using cache ---> c78c7188f804 Step 7/8 : ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/src/ Downloading 1.04MB/1.04MB ---> 23f47a028853 Step 8/8 : ADD nginx-1.19.0.tar.gz /tmp/ ---> 6ba2693b3084 Successfully built 6ba2693b3084 Successfully tagged myimg:v0.2 [root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v0.2 6ba2693b3084 27 seconds ago 8.54MB myimg v0.1 c78c7188f804 25 minutes ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker run --name test --rm -it myimg:v0.2 /bin/sh / # ls /usr/src/ nginx-1.18.0.tar.gz / # ls /tmp nginx-1.19.0 test.html / # exit [root@node1 test]#
提示:从上面的信息可以看到,在容器中的/usr/src/目录下nginx-1.18.0.tar.gz并没有展开,而在/tmp/下却把niginx-1.19.0.tar.gz展开为nginx-1.19.0;从build的过程来看,除开后面的ADD过程,其他过程都很快,并且明确告诉我们使用了cache,则意味着在本地仓库中有的镜像层,默认是共享的;
6、WORKDIR:该指令用于设定Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指令的工作目录;一个Dockerfile中可以多次使用WORKDIR来指定当前WORKDIR指令到下一个WORKDIR指令之间的指令的工作目录;语法格式WORKDIR
示例:
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." WORKDIR /var/www/ COPY html html/ COPY test.html /tmp/ WORKDIR /usr/ ADD http://nginx.org/download/nginx-1.18.0.tar.gz src/ ADD nginx-1.19.0.tar.gz /tmp/ [root@node1 test]#
提示:我们在dockerfile中指定了workdir的路径后,其后的指令就可以以上一个workdir指定的路径 为基准后面使用相对路径;
测试:制作镜像运行容器,看看是否把对应文件都添加到容器的指定目录里?
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." WORKDIR /var/www/ COPY html html/ COPY test.html /tmp/ WORKDIR /usr/ ADD http://nginx.org/download/nginx-1.18.0.tar.gz src/ ADD nginx-1.19.0.tar.gz /tmp/ [root@node1 test]# [root@node1 test]# docker build . -t myimg:v0.3 Sending build context to Docker daemon 1.05MB Step 1/10 : FROM busybox:latest ---> 78096d0a5478 Step 2/10 : MAINTAINER "qiuhom " ---> Using cache ---> bf9b966a914b Step 3/10 : LABEL version="1.0" ---> Using cache ---> 5dd2e4b3f594 Step 4/10 : LABEL description="this is test file \ that label-values can span multiple lines." ---> Using cache ---> 994f06ff65f8 Step 5/10 : WORKDIR /var/www/ ---> Running in 623002a4c418 Removing intermediate container 623002a4c418 ---> 7e6898b36dd5 Step 6/10 : COPY html html/ ---> 57ff5a48a104 Step 7/10 : COPY test.html /tmp/ ---> f66a1bf4040a Step 8/10 : WORKDIR /usr/ ---> Running in b905ff1b4529 Removing intermediate container b905ff1b4529 ---> 1fdceb9a6bfd Step 9/10 : ADD http://nginx.org/download/nginx-1.18.0.tar.gz src/ Downloading 1.04MB/1.04MB ---> 92868df29f5b Step 10/10 : ADD nginx-1.19.0.tar.gz /tmp/ ---> 68161c3beb90 Successfully built 68161c3beb90 Successfully tagged myimg:v0.3 [root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v0.3 68161c3beb90 11 seconds ago 8.54MB myimg v0.2 6ba2693b3084 18 minutes ago 8.54MB myimg v0.1 c78c7188f804 43 minutes ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker run --name test --rm -it myimg:v0.3 /bin/sh /usr # pwd /usr /usr # ls sbin src /usr # ls src/ nginx-1.18.0.tar.gz /usr # ls /tmp/ nginx-1.19.0 test.html /usr # ls /var/www/ html /usr # exit [root@node1 test]#
提示:可以看到我们制作的镜像启动为容器后,默认是我们指定的最后一个workdir的路径;
示例:使用环境变量指定workdi的路径;
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ENV webhome="/var/www/" src_home="/usr/" WORKDIR $webhome COPY html html/ COPY test.html /tmp/ WORKDIR $src_home ADD http://nginx.org/download/nginx-1.18.0.tar.gz src/ ADD nginx-1.19.0.tar.gz /tmp/ [root@node1 test]#
提示:我们在原有的Dockerfile中添加了ENV webhome="/var/www/" src_home="/usr/" 表示添加两个环境变量,而这两个环境的变量的值分别是“/var/www/” 和“/usr” 这样一来,在后面workdir引用该环境变量时 就会把对应的值给替换过去;dockerfile中变量引用同shell中的变量引用一样都是使用$符合引用变量;
测试:利用上面的Dockerfile编译成镜像,然后运行成容器,看看我们在dockerfile中定义的环境变量是否能够被容器所引用?
[root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v0.3 68161c3beb90 34 minutes ago 8.54MB myimg v0.2 6ba2693b3084 53 minutes ago 8.54MB myimg v0.1 c78c7188f804 About an hour ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker build . -t myimg:v0.4 Sending build context to Docker daemon 1.05MB Step 1/11 : FROM busybox:latest ---> 78096d0a5478 Step 2/11 : MAINTAINER "qiuhom" ---> Using cache ---> bf9b966a914b Step 3/11 : LABEL version="1.0" ---> Using cache ---> 5dd2e4b3f594 Step 4/11 : LABEL description="this is test file \ that label-values can span multiple lines." ---> Using cache ---> 994f06ff65f8 Step 5/11 : ENV webhome="/var/www/" src_home="/usr/" ---> Running in 82738c50a595 Removing intermediate container 82738c50a595 ---> 9f089c14778f Step 6/11 : WORKDIR $webhome ---> Running in 3e9d7d4276bf Removing intermediate container 3e9d7d4276bf ---> 94e17268d7ea Step 7/11 : COPY html html/ ---> cf3be18998db Step 8/11 : COPY test.html /tmp/ ---> 3b81cb058412 Step 9/11 : WORKDIR $src_home ---> Running in 70478cb9d405 Removing intermediate container 70478cb9d405 ---> e0d8ab9331f4 Step 10/11 : ADD http://nginx.org/download/nginx-1.18.0.tar.gz src/ Downloading 1.04MB/1.04MB ---> b4e546989783 Step 11/11 : ADD nginx-1.19.0.tar.gz /tmp/ ---> df3d040b5766 Successfully built df3d040b5766 Successfully tagged myimg:v0.4 [root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v0.4 df3d040b5766 4 minutes ago 8.54MB myimg v0.3 68161c3beb90 41 minutes ago 8.54MB myimg v0.2 6ba2693b3084 59 minutes ago 8.54MB myimg v0.1 c78c7188f804 About an hour ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker run --name test --rm -it myimg:v0.4 /bin/sh /usr # pwd /usr /usr # ls /var/www/ html /usr # ls /usr/src/ nginx-1.18.0.tar.gz /usr #
提示:可以看到我们指定的ENV环境变量是能够被WORKDIR说引用
7、ENV:用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其它指令(如ENV、ADD、COPY等)所调用;调用格式为$variable_name或${variable_name};语法格式ENV
示例:
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ENV web_home="/var/www/html/" COPY html ${web_home} [root@node1 test]#
提示:上面Dockerfile设置了环境变量web_home="/var/www/html" ,后面的COPY引用时直接使用${web_home}即可;COPY html ${web_home}表示把html目录中的文件复制到web_home这个变量所指定的目录中,即/var/www/html/;
测试:编译成镜像,看看是否把对应html目录下的文件复制到/var/www/html/目录下了?
[root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v0.4 df3d040b5766 17 minutes ago 8.54MB myimg v0.3 68161c3beb90 54 minutes ago 8.54MB myimg v0.2 6ba2693b3084 About an hour ago 8.54MB myimg v0.1 c78c7188f804 2 hours ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker build . -t myimg:v0.5 Sending build context to Docker daemon 1.05MB Step 1/6 : FROM busybox:latest ---> 78096d0a5478 Step 2/6 : MAINTAINER "qiuhom" ---> Using cache ---> bf9b966a914b Step 3/6 : LABEL version="1.0" ---> Using cache ---> 5dd2e4b3f594 Step 4/6 : LABEL description="this is test file \ that label-values can span multiple lines." ---> Using cache ---> 994f06ff65f8 Step 5/6 : ENV web_home="/var/www/html/" ---> Running in 4c136d790dd0 Removing intermediate container 4c136d790dd0 ---> 90e193e4e810 Step 6/6 : COPY html ${web_home} ---> e21e9479b0a7 Successfully built e21e9479b0a7 Successfully tagged myimg:v0.5 [root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v0.5 e21e9479b0a7 4 seconds ago 1.22MB myimg v0.4 df3d040b5766 17 minutes ago 8.54MB myimg v0.3 68161c3beb90 54 minutes ago 8.54MB myimg v0.2 6ba2693b3084 About an hour ago 8.54MB myimg v0.1 c78c7188f804 2 hours ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker run --name test --rm -it myimg:v0.5 /bin/sh / # ls /var/www/html/ test1.html test2.html / # exit [root@node1 test]#
提示:可以看到我们打包的镜像运行成容器后,ENV指定的环境变量目录里有html目录下的所有文件;
8、ARG:该指令用于编译阶段可以使用docker build --build-arg向dockerfile里ARG 指定的变量传递值;语法格式ARG
示例:
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home="/var/www/html/" COPY html ${web_home} [root@node1 test]#
提示:以上Dockerfile 指定了web_home变量的默认值是“/var/www/html/” 如果在我们build阶段没有使用--build-arg来向web_home传递值时,它默认就是“/var/www/html/”,如果我们使用了 --build-agr 指定web_home的值后,后面引用web_home变量的值就是我们用--build-arg传递给它的值;
测试:使用--build-arg向web_home传递值
[root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v0.5 e21e9479b0a7 14 minutes ago 1.22MB myimg v0.4 df3d040b5766 31 minutes ago 8.54MB myimg v0.3 68161c3beb90 About an hour ago 8.54MB myimg v0.2 6ba2693b3084 About an hour ago 8.54MB myimg v0.1 c78c7188f804 2 hours ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker build . --build-arg web_home="/usr/share/www/html/" -t myimg:v0.6 Sending build context to Docker daemon 1.05MB Step 1/6 : FROM busybox:latest ---> 78096d0a5478 Step 2/6 : MAINTAINER "qiuhom" ---> Using cache ---> bf9b966a914b Step 3/6 : LABEL version="1.0" ---> Using cache ---> 5dd2e4b3f594 Step 4/6 : LABEL description="this is test file \ that label-values can span multiple lines." ---> Using cache ---> 994f06ff65f8 Step 5/6 : ARG web_home="/var/www/html/" ---> Running in d8697abf9206 Removing intermediate container d8697abf9206 ---> 6abb65dab341 Step 6/6 : COPY html ${web_home} ---> 385cba27c288 Successfully built 385cba27c288 Successfully tagged myimg:v0.6 [root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v0.6 385cba27c288 6 seconds ago 1.22MB myimg v0.5 e21e9479b0a7 15 minutes ago 1.22MB myimg v0.4 df3d040b5766 32 minutes ago 8.54MB myimg v0.3 68161c3beb90 About an hour ago 8.54MB myimg v0.2 6ba2693b3084 About an hour ago 8.54MB myimg v0.1 c78c7188f804 2 hours ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker run --name test --rm -it myimg:v0.6 /bin/sh / # ls /usr/share/www/html/ test1.html test2.html / # exit [root@node1 test]#
提示:可以看到我们传递进去的路径下有html目录下的两个网页文件;这说明通过--build-arg 选项可以向Dockerfile里ARG指定指定的变量传递值的;
示例:引用变量给定变量默认值
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home COPY html ${web_home:-"/data/htdoc/"} [root@node1 test]#
提示:引用变量给定变量默认值的方式同shell中的用法一样;${web_home:-"/data/htdoc/"} 表示如果web_home这个变量的值未设定或者为空时,就使用默认的值“/data/htdoc/”这个值,如果设置了,那么设置的是什么值就是什么值;
测试:不使用--build-arg向web_home传递值,看看web_home是否会拿到默认值?
[root@node1 test]# docker build . -t myimg:v0.7 Sending build context to Docker daemon 1.05MB Step 1/6 : FROM busybox:latest ---> 78096d0a5478 Step 2/6 : MAINTAINER "qiuhom" ---> Using cache ---> bf9b966a914b Step 3/6 : LABEL version="1.0" ---> Using cache ---> 5dd2e4b3f594 Step 4/6 : LABEL description="this is test file \ that label-values can span multiple lines." ---> Using cache ---> 994f06ff65f8 Step 5/6 : ARG web_home ---> Running in 9d98f8e3a1f0 Removing intermediate container 9d98f8e3a1f0 ---> f164cc3e24ad Step 6/6 : COPY html ${web_home:-"/data/htdoc/"} ---> 4bedea2590b7 Successfully built 4bedea2590b7 Successfully tagged myimg:v0.7 [root@node1 test]# docker run --name test --rm -it myimg:v0.7 /bin/sh / # ls / bin data dev etc home proc root sys tmp usr var / # ls /data/ htdoc / # ls /data/htdoc/ test1.html test2.html / # exit [root@node1 test]#
提示:可以看到不想web_home传递值,默认就是使用我们给设定的默认值
测试:向web_home传递值,看看是否还会使用默认值呢?
[root@node1 test]# docker build . --build-arg web_home=/web/html/ -t myimg:v0.9 Sending build context to Docker daemon 1.05MB Step 1/6 : FROM busybox:latest ---> 78096d0a5478 Step 2/6 : MAINTAINER "qiuhom" ---> Using cache ---> bf9b966a914b Step 3/6 : LABEL version="1.0" ---> Using cache ---> 5dd2e4b3f594 Step 4/6 : LABEL description="this is test file \ that label-values can span multiple lines." ---> Using cache ---> 994f06ff65f8 Step 5/6 : ARG web_home ---> Using cache ---> f164cc3e24ad Step 6/6 : COPY html ${web_home:-"/data/htdoc/"} ---> 4b6993911e6d Successfully built 4b6993911e6d Successfully tagged myimg:v0.9 [root@node1 test]# docker run --name test --rm -it myimg:v0.9 /bin/sh / # ls / bin dev etc home proc root sys tmp usr var web / # ls /web/ html / # ls /web/html/ test1.html test2.html / # exit [root@node1 test]#
提示:可以看到通过--build-arg传递了web_home的值为“/web/htm/”后,默认的“/data/htdoc/”的值就不会生效;
9、VOLUME:用于在image中创建一个挂载点目录,以挂载Docker host上的卷或其它容器上的卷;语法格式 VOLUME
示例:
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home COPY html ${web_home:-"/data/htdoc/"} VOLUME ${web_home:-"/data/htdoc/"} [root@node1 test]#
提示:volume是指定镜像里的挂载点,如果该挂载点里面原来是有文件存在,在使用docker run 时,用-v指定把宿主机上的某个目录挂载到该挂载点时,默认会把原来有的文件复制新挂载的卷中;这里还需要特被说一下,这里指定卷是在镜像内部创建一个挂载点,运行成容器还需要我们手动的用-v去指定把那个目录挂载到该挂载点,如果不指定默认就是docker-managed 类型的卷;
测试:编译成镜像,然后运行成容器,看看我们指定的卷宗的文件会不会被覆盖掉?是否会有文件存在?
[root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v0.9 4b6993911e6d 21 minutes ago 1.22MB myimg v0.7 4bedea2590b7 23 minutes ago 1.22MB myimg v0.6 385cba27c288 30 minutes ago 1.22MB myimg v0.5 e21e9479b0a7 46 minutes ago 1.22MB myimg v0.4 df3d040b5766 About an hour ago 8.54MB myimg v0.3 68161c3beb90 2 hours ago 8.54MB myimg v0.2 6ba2693b3084 2 hours ago 8.54MB myimg v0.1 c78c7188f804 2 hours ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker build . -t myimg:v1.0 Sending build context to Docker daemon 1.05MB Step 1/7 : FROM busybox:latest ---> 78096d0a5478 Step 2/7 : MAINTAINER "qiuhom" ---> Using cache ---> bf9b966a914b Step 3/7 : LABEL version="1.0" ---> Using cache ---> 5dd2e4b3f594 Step 4/7 : LABEL description="this is test file \ that label-values can span multiple lines." ---> Using cache ---> 994f06ff65f8 Step 5/7 : ARG web_home ---> Using cache ---> f164cc3e24ad Step 6/7 : COPY html ${web_home:-"/data/htdoc/"} ---> Using cache ---> 4bedea2590b7 Step 7/7 : VOLUME ${web_home:-"/data/htdoc/"} ---> Running in 34cad9ca1f79 Removing intermediate container 34cad9ca1f79 ---> 9554284e4bba Successfully built 9554284e4bba Successfully tagged myimg:v1.0 [root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v1.0 9554284e4bba 2 minutes ago 1.22MB myimg v0.9 4b6993911e6d 24 minutes ago 1.22MB myimg v0.7 4bedea2590b7 26 minutes ago 1.22MB myimg v0.6 385cba27c288 33 minutes ago 1.22MB myimg v0.5 e21e9479b0a7 49 minutes ago 1.22MB myimg v0.4 df3d040b5766 About an hour ago 8.54MB myimg v0.3 68161c3beb90 2 hours ago 8.54MB myimg v0.2 6ba2693b3084 2 hours ago 8.54MB myimg v0.1 c78c7188f804 2 hours ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker run --name test --rm -it myimg:v1.0 /bin/sh / # ls / bin data dev etc home proc root sys tmp usr var / # ls /data/htdoc/ test1.html test2.html / # [root@node1 test]# [root@node1 test]# docker container inspect test -f {{.Mounts}} [{volume f3409b021267bd27d58c4b16fb1bc0dae77d4f92f7b5e6255f4ed26a6c27e459 /var/lib/docker/volumes/f3409b021267bd27d58c4b16fb1bc0dae77d4f92f7b5e6255f4ed26a6c27e459/_data /data/htdoc local true }] [root@node1 test]# ll /var/lib/docker/volumes/f3409b021267bd27d58c4b16fb1bc0dae77d4f92f7b5e6255f4ed26a6c27e459/_data total 8 -rw-r--r-- 1 root root 19 May 31 01:51 test1.html -rw-r--r-- 1 root root 19 May 31 01:51 test2.html [root@node1 test]#
提示:可以看到运行成容器后,默认会把我们指定卷挂载成docker-managed类型的卷;同时我们也看到了对应挂载点上目录会把原有文件复制到现volume中;
测试:手动指定宿主机目录挂载到挂载点,文件是否还会存在呢?
[root@node1 ~]# mkdir /work [root@node1 ~]# docker run --name test1 --rm -it -v /work:/data/htdoc/ myimg:v1.0 /bin/sh / # ls /data/htdoc/ / # [root@node1 ~]# ls /work/ [root@node1 ~]#
提示:手动指定挂载关系,它就不会把原有目录下的文件复制到现挂载目录中了;也就是说,人为手动指定挂载关系,宿主机上的的目录会覆盖容器内挂载点下的文件;只有docker自身管理的挂载的卷才会把原目录下的文件复制到现挂载目录里;
10、EXPOSE:用于为容器打开指定要监听的端口以实现与外部通信(暴露端口);语法格式 EXPOSE
示例:
[root@node1 test]# cat Dockerfile FROM busybox:latest MAINTAINER "qiuhom" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home COPY html ${web_home:-"/data/htdoc/"} VOLUME ${web_home:-"/data/htdoc/"} EXPOSE 80/tcp 443/tcp [root@node1 test]#
提示:以上dockerfile中暴露了tcp的80和443端口;在dockerfile中使用EXPOSE暴露端口,在运行成容器时,如果不使用-P来暴露端口,容器里的端口还是暴露不出来;这里只是build阶段明确说明要暴露80和443,而运行成容器我们需要使用-P来把build暴露的端口暴露出来;
测试:运行时不使用-P暴露端口,看看是否能够把80和443暴露出来呢?
[root@node1 test]# docker build . -t myimg:v1.1 Sending build context to Docker daemon 1.05MB Step 1/8 : FROM busybox:latest ---> 78096d0a5478 Step 2/8 : MAINTAINER "qiuhom" ---> Using cache ---> bf9b966a914b Step 3/8 : LABEL version="1.0" ---> Using cache ---> 5dd2e4b3f594 Step 4/8 : LABEL description="this is test file \ that label-values can span multiple lines." ---> Using cache ---> 994f06ff65f8 Step 5/8 : ARG web_home ---> Using cache ---> f164cc3e24ad Step 6/8 : COPY html ${web_home:-"/data/htdoc/"} ---> Using cache ---> 4bedea2590b7 Step 7/8 : VOLUME ${web_home:-"/data/htdoc/"} ---> Using cache ---> 9554284e4bba Step 8/8 : EXPOSE 80/tcp 443/tcp ---> Running in 8d7d5b4aab94 Removing intermediate container 8d7d5b4aab94 ---> 79c118ea9eb3 Successfully built 79c118ea9eb3 Successfully tagged myimg:v1.1 [root@node1 test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimg v1.1 79c118ea9eb3 4 seconds ago 1.22MB myimg v1.0 9554284e4bba 24 minutes ago 1.22MB myimg v0.9 4b6993911e6d 46 minutes ago 1.22MB myimg v0.7 4bedea2590b7 48 minutes ago 1.22MB myimg v0.6 385cba27c288 55 minutes ago 1.22MB myimg v0.5 e21e9479b0a7 About an hour ago 1.22MB myimg v0.4 df3d040b5766 About an hour ago 8.54MB myimg v0.3 68161c3beb90 2 hours ago 8.54MB myimg v0.2 6ba2693b3084 2 hours ago 8.54MB myimg v0.1 c78c7188f804 3 hours ago 1.22MB busybox latest 78096d0a5478 2 weeks ago 1.22MB [root@node1 test]# docker run --name test --rm -it myimg:v1.0 /bin/sh / # [root@node1 test]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ca4cea9a6f58 myimg:v1.0 "/bin/sh" 15 seconds ago Up 15 seconds test [root@node1 test]# docker container port test [root@node1 test]#
提示:可以看到运行时,我们不使用-P来暴露端口是把容器内部端口暴露不出来的;
示例:使用-P来暴露dockerfile里定义的端口
[root@node1 test]# docker run --name test --rm -it -P myimg:v1.1 /bin/sh / # [root@node1 test]# docker container port test 443/tcp -> 0.0.0.0:32768 80/tcp -> 0.0.0.0:32769 [root@node1 test]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a78f6cebc0de myimg:v1.1 "/bin/sh" 19 seconds ago Up 19 seconds 0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp test [root@node1 test]#
提示:可以看到使用-P就可以在运行时把build阶段定义的暴露端口全部给暴露出来;