版权声明:本文为博主原创文章,转载请指明地址。 https://blog.csdn.net/Mr_rsq/article/details/84840823
文章目录
一般自制镜像有两种方法:
- DockerFile(下文介绍这个)
- 基于容器做镜像(上文已经介绍过)
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为起始路径;
注意:在路径中有空白字符时,通常使用第二种格式
文件复制准则:
- 必须是build上下文中的路径,不能是其父目录中的文件
- 如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
- 如果指定了多个,或在中使用了通配符,则必须是一个目录,且必须以/结尾
- 如果事先不存在,它会被自动创建,这包括其父目录路径
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>"]
操作准则
- 同COPY指令
- 如果为URL且不以/结尾,则指定的文件将被下载并直接被创建为;如果以/结尾,则文件名URL指定的文件将被直接下载并保存为/
- 如果是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于“tar -xf”命令;然而,通过URL获取到的tar文件将不会自动展开;
- 如果有多个,或其间接或直接使用了通配符,则必须是一个以/结尾的目录路径;如果不以/结尾。则其被视作一个普通文件,的内容将被直接写入到;
实例:
# 修改配置文件如下
[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指令应该格外小心,因为新构建过程的上下文在缺少指定的源文件时会失败。
参考文档: