(四)Dockerfile Instruction

版权声明:本文为博主原创文章,转载请指明地址。 https://blog.csdn.net/Mr_rsq/article/details/84840823

一般自制镜像有两种方法:

  1. DockerFile(下文介绍这个)
  2. 基于容器做镜像(上文已经介绍过)

Tips:变量${NAME:-name}${NAME:+name}的区别

[root@docker-node1 ~]# echo ${NAME:-tom}
tom
[root@docker-node1 ~]# echo ${NAME:-jerry}
jerry
[root@docker-node1 ~]# echo ${NAME:+jerry}

[root@docker-node1 ~]# echo ${NAME:+tom}

[root@docker-node1 ~]#

1 指定基准镜像(FROM)

FROM

  • From指令是最重要的一个且必须为Dockerfile文件开篇的第一个非注释行,用于为映像文件构建过程指定基准镜像,后续的指令运行于此基准镜像所提供的运行环境。
  • 实践中,基准镜像可以是任何可用的镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时,则会从Docker Hub Registry上拉取所需的镜像文件。如果找不到指定的镜像文件,docker build会返回一个错误信息。

语法:

FROM <repository>[:<tag>]
FROM <repository>@<digest>
	<repository>:指定作为base image的名称;
	<tag>:base image的标签,为可选项,省略时默认为latest;

2 打标签(MAINTAINER/LABEL)

MAINTAINIER(depreacted)

  • 用于让Dockerfile制作者提供本人的详细信息。
  • Dockerfile并不限制MAINTAINER指令可出现的文职,但推荐将其放置于FROM指令之后。

语法:

MAINTAINER <authtor's detail>
	<authtor's detail>可以是任何文本信息,但约定俗成地使用作者名称及邮件地址
	MAINTAINER "RSQ <[email protected]>"

LABEL增加元数据到镜像中,key-value格式

语法:

LABEL <key>=<value> <key>=<value> <key>=<value> ...
eg. LABEL auth="RSQ<[email protected]>"

3 复制文件(COPY)

COPY

  • 用于从Docker主机复制文件至创建的新映像文件

语法:

COPY <src> ... <dest>
COPY ["<src>" ... "dest"]
	<src>:要复制的源文件或目录,支持使用通配符
	<dest>:目标路径,即正在创建image的文件系统路径;建议为<dest>使用绝对路径,否则,COPY指定则以WORKDIR为起始路径;
注意:在路径中有空白字符时,通常使用第二种格式

文件复制准则:

  1. 必须是build上下文中的路径,不能是其父目录中的文件
  2. 如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
  3. 如果指定了多个,或在中使用了通配符,则必须是一个目录,且必须以/结尾
  4. 如果事先不存在,它会被自动创建,这包括其父目录路径

PS: 在Dockerfile文件中,文件指令越多,docker镜像层就越多,那么效率就越低,写指令时尽量高效

实例:(以下所有操作都基于此)
创建一个镜像目录

[root@docker-node1 ~]# mkdir img1
[root@docker-node1 ~]# cd img1
[root@docker-node1 img1]# vim Dockerfile
# Description test image
FROM busybox:latest
#FROM busybox@Csdcsdvfdfv Hash
MAINTAINER "RSQ <[email protected]>"
#LABEL maintainer="RSQ <[email protected]>" 
COPY index.html /data/web/html/

创建一个index.html文件

[root@docker-node1 img1]# echo "<h1>busybox httpd server</h1>" >index.html

[root@docker-node1 img1]# docker build -t rsqhttpd:v0.1-1 ./
Sending build context to Docker daemon  4.096kB
Step 1/3 : FROM busybox:latest
 ---> 59788edf1f3e
Step 2/3 : MAINTAINER "RSQ<[email protected]>"
 ---> Running in f4873f2f8f10
Removing intermediate container f4873f2f8f10
 ---> 7a2e016afae0
Step 3/3 : COPY index.html /data/web/html/
 ---> b26b79e07a12
Successfully built b26b79e07a12
Successfully tagged rsqhttpd:v0.1-1
[root@docker-node1 img1]# docker images
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
rsqhttpd                                        v0.1-1              b26b79e07a12        18 seconds ago      1.15MB

以此镜像运行容器并执行命令

[root@docker-node1 img1]# docker run --name rsqhttpd1 --rm rsqhttpd:v0.1-1 cat /data/web/html/index.html
<h1>busybox httpd server</h1>

4 打包文件(ADD)

ADD

  • 指令类似于COPY指令,ADD支持使用TAR文件和URL路径

语法:

ADD <src> ... <dest>
ADD ["<src>" ... "<dest>"]

操作准则

  1. 同COPY指令
  2. 如果为URL且不以/结尾,则指定的文件将被下载并直接被创建为;如果以/结尾,则文件名URL指定的文件将被直接下载并保存为/
  3. 如果是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于“tar -xf”命令;然而,通过URL获取到的tar文件将不会自动展开;
  4. 如果有多个,或其间接或直接使用了通配符,则必须是一个以/结尾的目录路径;如果不以/结尾。则其被视作一个普通文件,的内容将被直接写入到;

实例:

# 修改配置文件如下
[root@docker-node1 img1]# cat Dockerfile
# Description test image 
FROM busybox:latest
MAINTAINER "RSQ<[email protected]>"
#LABEL auth="RSQ<[email protected]>"
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
ADD http://nginx.org/download/nginx-1.15.6.tar.gz /usr/local/src/

[root@docker-node1 ~]# docker run --name rsqhttpd2 --rm rsqhttpd:v0.1-2 ls /usr/local/src/
nginx-1.15.6.tar.gz
[root@docker-node1 ~]# docker run --name rsqhttpd2 --rm rsqhttpd:v0.1-2 ls /etc/yum.repos.d/CentOS-Base.repo
CentOS-CR.repo
CentOS-Debuginfo.repo
CentOS-Media.repo
CentOS-Sources.repo
CentOS-Vault.repo
CentOS-fasttrack.repo
docker-ce.repo
epel.repo

先下载gz文件

[root@docker-node1 img1]# wget http://nginx.org/download/nginx-1.15.6.tar.gz

修改配置文件,使下载的gz文件直接解压到指定镜像中

[root@docker-node1 img1]# cat Dockerfile
# Description test image 
FROM busybox:latest
MAINTAINER "RSQ<[email protected]>"
#LABEL auth="RSQ<[email protected]>"
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
#ADD http://nginx.org/download/nginx-1.15.6.tar.gz /usr/local/src/
ADD nginx-1.15.6.tar.gz /usr/local/src/
[root@docker-node1 img1]# docker build -t rsqhttpd:v0.1-3 ./

换个终端查看会发现此gz文件被直接解压成目录了

[root@docker-node1 ~]# docker run --name rsqhttpd2 --rm rsqhttpd:v0.1-3 ls /usr/local/src/
nginx-1.15.6
[root@docker-node1 ~]# docker run --name rsqhttpd2 --rm rsqhttpd:v0.1-3 ls /usr/local/src/nginx-1.15.6/
CHANGES
CHANGES.ru
LICENSE
README
auto
conf
configure
contrib
html
man
src

5 工作目录(WORKDIR)

WORKDIR

  • 用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定设定工作目录。

语法:

	WORKDIR <dirpath>
		在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为起始路径,不过,其是相对此前的一个WORKDIR指令的路径
		另外,WORKDIR也可调用ENV指令定义的变量
例如:
		WORKDIR <dirpath>
		WORKDIR $STATEPATH

WORKDIR每次只影响从他开始向后的指令,可指定多次

[root@docker-node1 img1]# cat Dockerfile
# Description test image 
FROM busybox:latest
MAINTAINER "RSQ<[email protected]>"
#LABEL auth="RSQ<[email protected]>"
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
#ADD http://nginx.org/download/nginx-1.15.6.tar.gz /usr/local/src/
WORKDIR /usr/local/

ADD nginx-1.15.6.tar.gz ./src/

6 卷(VOLUME)

VOLUME:

  • 用于在image中创建一个挂载点目录,以挂载Docker host上的卷或其它容器上的卷。

语法:

	VOLUME <mountpoint>
	VOLUME ["<mountpoint>"]

如果挂载点目录路径下已经存在其它文件,docker run命令会在卷挂在完成后将此前的所有文件复制到新挂载的卷中

但是此卷不能指定宿主机的挂载点位置

# 在配置文件中追加一行,用于指定存放数据的目录
[root@docker-node1 img1]# tail -1 Dockerfile
VOLUME /data/mysql/
[root@docker-node1 img1]# docker build -t rsqhttpd:v0.1-4 ./
Sending build context to Docker daemon  1.052MB
Step 1/7 : FROM busybox:latest
 ---> 59788edf1f3e
Step 2/7 : MAINTAINER "RSQ<[email protected]>"
 ---> Using cache
 ---> 7a2e016afae0
Step 3/7 : COPY index.html /data/web/html/
 ---> Using cache
 ---> b26b79e07a12
Step 4/7 : COPY yum.repos.d /etc/yum.repos.d/
 ---> Using cache
 ---> 6c001ee11bdc
Step 5/7 : WORKDIR /usr/local/
 ---> Running in d9b3bce6018b
Removing intermediate container d9b3bce6018b
 ---> 3cc00db1782e
Step 6/7 : ADD nginx-1.15.6.tar.gz ./src/
 ---> d335ee7acac1
Step 7/7 : VOLUME /data/mysql/
 ---> Running in f260e09af8bb
Removing intermediate container f260e09af8bb
 ---> 70187826a8ac
Successfully built 70187826a8ac
Successfully tagged rsqhttpd:v0.1-4

[root@docker-node1 ~]# docker run --name rsqhttpd4 --rm rsqhttpd:v0.1-4 mount | grep "/data/mysql"
/dev/mapper/centos-root on /data/mysql type xfs (rw,seclabel,relatime,attr2,inode64,noquota

7 为容器打开指定端口(EXPOSE)

EXPOSE

  • 用于为容器打开指定要监听的端口以实现与外部通信

语法:

EXPOSE <port>[/<protocol>] [<port>[/<protocol>]...]
	<protocol>用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议。
EXPOSE指令可一次指定多个端口,例如:
	EXPOSE 11621/udp 11621/tcp

实例:

[root@docker-node1 img1]# docker build -t rsqhttpd:v0.1-5 ./
[root@docker-node1 ~]# docker run --name rsqhttpd5 --rm rsqhttpd:v0.1-5 /bin/httpd -f -h /data/web/html
[root@docker-node1 ~]# docker inspect rsqhttpd5  # 找下IP地址
[root@docker-node1 ~]# curl 172.17.0.3
<h1>busybox httpd server</h1>
[root@docker-node1 ~]# docker port rsqhttpd5   # 这样看不到暴露端口
[root@docker-node1 ~]#

# 杀掉重新启动容器(加个-P选项)
[root@docker-node1 ~]# docker kill rsqhttpd5
rsqhttpd5
[root@docker-node1 ~]# docker run --name rsqhttpd5 --rm -P rsqhttpd:v0.1-5 /bin/httpd -f -h /data/web/html
[root@docker-node1 ~]# docker port rsqhttpd5
80/tcp -> 0.0.0.0:32768

浏览器访问
在这里插入图片描述

8 环境变量(ENV)

ENV:

  • 用于为镜像定义所需要的环境变量,并可被Dockerfile文件中位于其后的其它指令(如ENV、ADD、COPY等)多调用

语法:

ENV <key> <value>
ENV <key>=<value> ...

调用格式为 $variable_name 或 ${variable_name}
  • 第一种格式中,之后的所有内容均会被视作其的组成部分,因此,一次只能设置一个变量;
  • 第二种格式可用一次设置多个变量,每个变量为一个"="的键值对,如果中包含空格,可以以反斜线()进行转义,也可通过对加引号禁行标示;另外,反斜线也可用于续行。
  • 定义多个变量时,建议使用第二种方式,以便在同一层中完成所有功能。

实例:

[root@docker-node1 img1]# vim Dockerfile
# Description test image 
FROM busybox:latest
MAINTAINER "RSQ<[email protected]>"
#LABEL auth="RSQ<[email protected]>"
ENV DOC_ROOT=/data/web/html/ \
    WEB_SERVER_PAC="nginx-1.15.6"

COPY index.html ${DOC_ROOT:-/data/web/html/}
COPY yum.repos.d /etc/yum.repos.d/
#ADD http://nginx.org/download/nginx-1.15.6.tar.gz /usr/local/src/
WORKDIR /usr/local/

ADD ${WEB_SERVER_PAC}.tar.gz ./src/

VOLUME /data/mysql/

EXPOSE 80/tcp
[root@docker-node1 img1]# docker build -t rsqhttpd:v0.1-6 ./
Sending build context to Docker daemon  1.052MB
Step 1/9 : FROM busybox:latest
 ---> 59788edf1f3e
Step 2/9 : MAINTAINER "RSQ<[email protected]>"
 ---> Using cache
 ---> 7a2e016afae0
Step 3/9 : ENV DOC_ROOT=/data/web/html/     WEB_SERVER_PAC="nginx-1.15.6"
 ---> Running in 1d942d6a59b5
Removing intermediate container 1d942d6a59b5
 ---> 3aef5ec0534e
Step 4/9 : COPY index.html ${DOC_ROOT:-/data/web/html/}
 ---> 2a42834e11c0
Step 5/9 : COPY yum.repos.d /etc/yum.repos.d/
 ---> e1bfa3dec3b4
Step 6/9 : WORKDIR /usr/local/
 ---> Running in 4b5d8667dafb
Removing intermediate container 4b5d8667dafb
 ---> d7b3c1989b7e
Step 7/9 : ADD ${WEB_SERVER_PAC}.tar.gz ./src/
 ---> acba2ce0ec92
Step 8/9 : VOLUME /data/mysql/
 ---> Running in 9a213fe2d6e3
Removing intermediate container 9a213fe2d6e3
 ---> e6eb63d07f46
Step 9/9 : EXPOSE 80/tcp
 ---> Running in e50e44013c58
Removing intermediate container e50e44013c58
 ---> 432cd39dd20c
Successfully built 432cd39dd20c
Successfully tagged rsqhttpd:v0.1-6
[root@docker-node1 ~]# docker run --name rsqhttpd5 --rm rsqhttpd:v0.1-6 ls /usr/local/
src
[root@docker-node1 ~]# docker run --name rsqhttpd5 --rm rsqhttpd:v0.1-6 ls /usr/local/src/nginx-1.15.6
CHANGES
CHANGES.ru
LICENSE
README
auto
conf
configure
contrib
html
man
src
[root@docker-node1 ~]# docker run --name rsqhttpd5 --rm rsqhttpd:v0.1-6 printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=7bd9938061c1
DOC_ROOT=/data/web/html/
WEB_SERVER_PAC=nginx-1.15.6
HOME=/root

# 手动指定环境变量
[root@docker-node1 ~]# docker run --name rsqhttpd5 --rm -e WEB_SERVER_PAC="nginx-1.15.8" rsqhttpd:v0.1-6 printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=7d177a9f3da6
WEB_SERVER_PAC=nginx-1.15.8
DOC_ROOT=/data/web/html/
HOME=/root

9 (RUN)

[root@docker-node1 img1]# cat Dockerfile
# Description test image 
FROM busybox:latest
MAINTAINER "RSQ<[email protected]>"
#LABEL auth="RSQ<[email protected]>"
ENV DOC_ROOT=/data/web/html/ \
    WEB_SERVER_PAC="nginx-1.15.6.tar.gz"

COPY index.html ${DOC_ROOT:-/data/web/html/}
COPY yum.repos.d /etc/yum.repos.d/
ADD http://nginx.org/download/${WEB_SERVER_PAC} /usr/local/src/
WORKDIR /usr/local/

#ADD ${WEB_SERVER_PAC} ./src/

VOLUME /data/mysql/

EXPOSE 80/tcp

RUN cd /usr/local/src/ && \
    tar xf ${WEB_SERVER_PAC}
[root@docker-node1 ~]# docker run --name rsqhttpd5 --rm -P rsqhttpd:v0.1-7 ls /usr/local/src/
nginx-1.15.6
nginx-1.15.6.tar.gz

# 配置yum源,安装nginx
FROM centos
RUN yum -y install epel-release && yum makecache && yum install nginx

10 (CMD)

CMD:

  • 类似于RUN指令,CMD指令也可用于运行任何命令或应用程序,不过,二者的运行时间点不同。
  • RUN指令运行于映像文件的构建过程中,而CMD指令运行于基于Dockerfile构建出新映像文件启动一个容器时。
  • CMD指令的首要目的在于启动的容器指定默认要运行的程序,且其运行结束后,容器也终止;不过,CMD指定的命令其可以被docker run的命令行选项所覆盖。
  • 在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效

语法:

CMD <command>
CMD ["<executable>","<param1>","<param2>"]
CMD ["<param1>","<param2>"]

前两种语法格式的意义同RUN
第三种则用于ENTRYPOINT指令提供默认参数

实例:

[root@docker-node1 ~]# mkdir img2
[root@docker-node1 ~]# cd img2
[root@docker-node1 img2]# vim Dockerfile
FROM busybox
LABEL auth="RSQ <[email protected]>" app="httpd"

ENV WEB_DOC_ROOT="/data/web/html/"

RUN mkdir -p $WEB_DOC_ROOT && \
    echo "<h1>This is a test.<h1>" > ${WEB_DOC_ROOT}index.html

CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
[root@docker-node1 img2]# docker build -t rsqhttpd:v0.2-1 ./

# 启动,此刻容器会处于运行状态,但不会有交互界面出现
[root@docker-node1 ~]# docker run --name tinyweb1 -it --rm rsqhttpd:v0.2-1

# 可以看到,此CMD运行环境为sh的子shell
[root@docker-node1 ~]# docker image inspect rsqhttpd:v0.2-1
......
            "Cmd": [
                "/bin/sh",
                "-c",
                "/bin/httpd -f -h ${WEB_DOC_ROOT}"
......

# 用exec起交互
[root@docker-node1 ~]# docker exec -it tinyweb1 /bin/sh
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/httpd -f -h /data/web/html/
    6 root      0:00 /bin/sh
   12 root      0:00 ps
/ #

# 测试
[root@docker-node1 ~]# vim Dockerfile
# CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
CMD ["/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]

# 运行会报错
[root@docker-node1 ~]# docker run --name tinyweb1 -it --rm rsqhttpd:v0.2-2
httpd: can't change directory to ' ${WEB_DOC_ROOT}': No such file or directory

# 手动把CMD运行的环境变为bash的子进程
[root@docker-node1 ~]# vim Dockerfile
CMD ["/bin/sh","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]

11 (ENTRYPOINT)

ENTRYPOINT:

  • 类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序。
  • 与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序,不过,docker run命令的–entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序。

语法:

ENTRYPOINT <command>
ENTRYPOINT ["<executable>","<param1>","<param2>"...]

注意:

  • docker run 命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后作为其参数使用。
  • Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效。

实例1:

[root@docker-node1 img2]# vim Dockerfile
ENTRYPOINT /bin/httpd -f -h ${WEB_DOC_ROOT}
[root@docker-node1 img2]# docker build -t rsqhttpd:v0.2-4 ./
[root@docker-node1 ~]# docker run --name tinyweb1 -it -P --rm rsqhttpd:v0.2-4
[root@docker-node1 ~]# docker image inspect rsqhttpd:v0.2-4
......
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "ENTRYPOINT [\"/bin/sh\" \"-c\" \"/bin/httpd -f -h ${WEB_DOC_ROOT}\"]"
            ],

            "Entrypoint": [
                "/bin/sh",
                "-c",
                "/bin/httpd -f -h ${WEB_DOC_ROOT}"
......

# 可以看到默认ENTRYPOINT直接执行命令,是会以/bin/sh -c的,要想指定shell,则加双引号
[root@docker-node1 img2]# vim Dockerfile
ENTRYPOINT ["/bin/sh","-c"]

# CMD是可以给ENTRYPOINT传参操作,不过解析不了变量
# 解析不了变量,若想运行,则需要把CMD跟上具体路径信息
[root@docker-node1 img2]# vim Dockerfile
CMD ["/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
ENTRYPOINT ["/bin/sh","-c"] 
[root@docker-node1 img2]# docker build -t rsqhttpd:v0.2-5 ./
[root@docker-node1 ~]# docker image inspect rsqhttpd:v0.2-5   
......
            "Cmd": [
                "/bin/httpd",
                "-f",
                "-h ${WEB_DOC_ROOT}"
            ],
            "Entrypoint": [
                "/bin/sh",
                "-c"
            ],
......

# 在docker run指定的命令不会覆盖ENTRYPOINT指定的命令
# 除非加--entrypoint,但是大多数情况下是不会覆盖的
[root@docker-node1 ~]# docker run --name tinyweb1 -it -P --rm rsqhttpd:v0.2-4 "ls /data/"
[root@docker-node1 ~]# docker run --name tinyweb1 -it -P --entrypoint "/bin/ls /data/" --rm rsqhttpd:v0.2-4

[root@docker-node1 ~]# docker run --name tinyweb1 -it -P rsqhttpd:v0.2-5
[root@docker-node1 ~]# docker ps -a   # 会发现CMD当参数传给了/bin/sh -c
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
1e147126d436        rsqhttpd:v0.2-5     "/bin/sh -c /bin/htt…"   7 seconds ago       Exited (0) 7 seconds ago                       tinyweb1

# 若在docker run后面跟命令,则会覆盖dockerfile中的CMD指令
[root@docker-node1 ~]# docker run --name tinyweb1 -it -P --rm rsqhttpd:v0.2-5 "ls /data"
web

实例2:制作第三个镜像,使得nginx可以根据环境变量接收参数

[root@docker-node1 ~]# mkdir img3
[root@docker-node1 ~]# cd img3
[root@docker-node1 img3]# cat entrypoint.sh 
#!/bin/sh
#
cat > /etc/nginx/conf.d/www.conf <<EOF
server {
	server_name $HOSTNAME;
	listen ${IP:-0.0.0.0}:${PORT:-80};
	root ${NGX_DOC_ROOT:-/usr/share/nginx/html};
}
EOF

exec "$@" 
[root@docker-node1 img3]# echo "This is a new test page." >>index.html
[root@docker-node1 img3]# vim Dockerfile
FROM nginx:1.14-alpine
LABEL maintainer="RSQ <[email protected]>"

ENV NGX_DOC_ROOT="/data/web/html/"

ADD index.html ${NGX_DOC_ROOT}
ADD entrypoint.sh /bin/

EXPOSE 80/tcp 8080/tcp

CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
[root@docker-node1 ~]# docker run --name rsqweb1 -it -P --rm rsqhttpd:v0.3-1

[root@docker-node1 ~]# curl 172.17.0.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
.....

# 传参使用 -e 参数
[root@docker-node1 ~]# docker run --name rsqweb1 -it -P -e "PORT=8080" --rm rsqhttpd:v0.3-1
[root@docker-node1 ~]# docker port rsqweb1
80/tcp -> 0.0.0.0:32777
8080/tcp -> 0.0.0.0:32776
[root@docker-node1 ~]# docker exec -it rsqweb1 /bin/sh
/ # cat /etc/nginx/conf.d/www.conf 
server {
	server_name 1e05413ff76b;
	listen 0.0.0.0:8080;
	root /data/web/html/;
}
/ #

12 (USER)

USER

  • 用于指定运行image时的或运行Dockerfile中任何RUN、CMD或ENTRYPOINT指令指定的程序时的用户名或UID。
  • 默认情况下,container的运行身份为root用户。

语法:

USER <UID>|<UserName>
  • 需要注意的是,可以为任意数字,但实践中其必须为/etc/passwd中某用户的有效UID,否则,docker run命令将运行失败。

13 (HEALTHCHECK)

HEALTHCHECK

  • 即健康检查
  • 该指令可以使docker检测一个容器是否还处于工作状态,如通过curl或wget来检测web服务是否正常,默认情况下如果测试失败三次(每次默认时长30s),则docker会停掉此容器。

语法:

HEALTHCHECK [OPTION] CMD command (check container health by running a command inside the container)

OPTIONS:
	--interval=DURATION (default 30s)
	--timeout=DURATION (default 30s)
	--start-period=DURATION (default 30s)
	--retries=N (default 30s
	
For Example:
	HEALTHCHECK --start-period=3s CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT:-80}/

实例:

[root@docker-node1 img3]# vim Dockerfile
FROM nginx:1.14-alpine
LABEL maintainer="RSQ <[email protected]>"

ENV NGX_DOC_ROOT="/data/web/html/"

ADD index.html ${NGX_DOC_ROOT}
ADD entrypoint.sh /bin/

EXPOSE 80/tcp 8080/tcp

HEALTHCHECK --start-period=3s CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT:-80}/

CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
[root@docker-node1 img3]# docker build -t rsqhttpd:v0.3-5 ./
Sending build context to Docker daemon  4.096kB
Step 1/9 : FROM nginx:1.14-alpine
 ---> 14d4a58e0d2e
Step 2/9 : LABEL maintainer="RSQ <[email protected]>"
 ---> Using cache
 ---> 8d364a9b2cd3
Step 3/9 : ENV NGX_DOC_ROOT="/data/web/html/"
 ---> Using cache
 ---> 870b2ccd487b
Step 4/9 : ADD index.html ${NGX_DOC_ROOT}
 ---> Using cache
 ---> 2ea04df6e8e6
Step 5/9 : ADD entrypoint.sh /bin/
 ---> Using cache
 ---> 4d9520e9cd87
Step 6/9 : EXPOSE 80/tcp 8080/tcp
 ---> Using cache
 ---> dd246f981752
Step 7/9 : HEALTHCHECK --start-period=3s CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT:-80}/
 ---> Running in bfaf04b774c9
Removing intermediate container bfaf04b774c9
 ---> 7888ab45113d
Step 8/9 : CMD ["/usr/sbin/nginx","-g","daemon off;"]
 ---> Running in 0a3cd6dbe086
Removing intermediate container 0a3cd6dbe086
 ---> 89e24209ac1f
Step 9/9 : ENTRYPOINT ["/bin/entrypoint.sh"]
 ---> Running in 52a0a3304c19
Removing intermediate container 52a0a3304c19
 ---> fa533436e972
Successfully built fa533436e972
Successfully tagged rsqhttpd:v0.3-5

# 启动容器,隔一会会有测试信息输出,默认30s
[root@docker-node1 ~]# docker run --name rsqweb1 -it -P -e "PORT=8080" --rm rsqhttpd:v0.3-5
127.0.0.1 - - [25/Nov/2018:15:58:15 +0000] "GET / HTTP/1.1" 200 25 "-" "Wget" "-"
127.0.0.1 - - [25/Nov/2018:15:58:45 +0000] "GET / HTTP/1.1" 200 25 "-" "Wget" "-"
[root@docker-node1 ~]# docker exec -it rsqweb1 /bin/sh
/ # netstat -lntup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1/nginx -g daemon o
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx -g daemon o

14 (ARG)

ARG

  • 可自定义参数变量,如每次修改版本号只需要修改变量值即可。

实例:

[root@docker-node1 img3]# vim Dockerfile 

FROM nginx:1.14-alpine

ARG author="RSQ <[email protected]>"
LABEL maintainer="${author}"

ENV NGX_DOC_ROOT="/data/web/html/"

ADD index.html ${NGX_DOC_ROOT}
ADD entrypoint.sh /bin/

EXPOSE 80/tcp 8080/tcp

HEALTHCHECK --start-period=3s CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT:-80}/

CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
[root@docker-node1 img3]# docker build -t rsqhttpd:v0.3-6 ./
[root@docker-node1 ~]# docker image inspect rsqhttpd:v0.3-6
            "Labels": {
                "maintainer": "RSQ <[email protected]>"

15 (ONBUILD)

ONBUILD

  • 用于在Dockerfile中定义一个触发器
  • 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指令应该格外小心,因为新构建过程的上下文在缺少指定的源文件时会失败。

参考文档:

Dockerfile Instruction 官方文档

猜你喜欢

转载自blog.csdn.net/Mr_rsq/article/details/84840823
今日推荐