Docker基础 - 07Dockerfile

一、Dockerfile

Dockerfile is nothing but the source code for building Docker images

Docker runs instructions in a Dockerfile in order

Environment variables can used in certain instructions as vaiables to be interpreted by the Dockerfile

[root@cl-node03 docker]# echo ${NAME:-tom}
tom
[root@cl-node03 docker]# NAME=jerry
[root@cl-node03 docker]# echo ${NAME:-tom}
jerry
[root@cl-node03 docker]# echo ${NAME:+tom}
tom
[root@cl-node03 docker]# unset NAME
[root@cl-node03 docker]# echo ${NAME:+tom}  # 输出空

  

二、Dockerfile Instructions

2.1 FROM

  • FROM 指令是最重的一个且必须为Dockerfile 文件开篇的第一个非注释行,
  • 用于为映像文件构建过程指定基准镜像, 后续的指令运行于此基准镜像所提供的运行环境
  • 基准镜像可以是任何可用镜像文件。
  • docker build 会在docker主机上查找指定的镜像文件,不存在时,会从Docker Hub Registry 上拉取所需的镜像文件,
  • 找不到指定镜像文件,docker build 返回一个错误信息
  • 语法:  FROM <repository>[:<tag>]

2.2 MAINTANIER

  • 用于让 Dockerfile 制作者提供本人的详细信息。
  • Dockerfile 并不限制 MAINTAINER 指令出现的位置,推荐在FROM指令之后。
  • 语法: MAINTAINER <authtor's detail>

2.3 LABEL

  • The LABEL instruction adds metadata to an image
  • To include spaces within a LABEL value, use quotes and backslashes。
  • 语法: LABEL <key>=<value>  <key>=<value>   <key>=<value> ......

2.4 COPY

  • COPY 从 Docker 宿主机复制文件到创建的新映像文件
  • 语法: COPY <src> ... <dest>   或 COPY ["<src",...,"<dest>"]
  • <src>: 要复制的源文件或目录,支持使用通配符
  • <dest>: 目标路径,正在创建的image的文件系统路径;建议使用绝对路径,否则COPY 指定则以WORKDIR为起始路径。
  • 复制准则:
  • <src>必须是build上下文中的路径,不能是其父目录中的文件。必须以Dockerfile所在的目录为起始路径。
  • <src>为目录,则其内部的文件或子目录都会被递归复制,但<src>目录自身不会复制
  • 指定了多个<src>,或者<src>使用了通配符,则<dest>必须是目录,且必须以/结尾
  • <dest>事先不存在,将会被自动创建,这包括其父目录路径。

2.5 ADD

  • ADD指令类似于COPY指令, ADD支持使用TAR文件和URL路径
  • 语法: ADD <src> ... <dest>  或  ADD ["<src",...,"<dest>"]
  • 操作准则:
  • 如果src为URL且dest不以/结尾,则src指定的文件将被下载并直接被创建为 dest; 如果dest以/结尾,则URL指定的文件将被下载并保存为dest/filename;
  • 如果src是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,类似于"tar -x"命令;通过URL获取到的tar文件不会自动解压;
  • 如果src有多个,或其直接或间接使用了通配符,则dest 必须是以/结尾的目录路径;如果不以/结尾,则其被视作一个普通文件,src 的内容将被直接写入到 dest;


[root@cl-node03 docker_image_build]# vi Dockerfile 
[root@cl-node03 docker_image_build]# cat Dockerfile 
FROM busybox:latest
MAINTAINER "Beapx <bearpx@kunking.com>"
COPY index.html  /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
ADD http://nginx.org/download/nginx-1.20.0.tar.gz  /usr/local/src/

[root@cl-node03 docker_image_build]# ls
Dockerfile  index.html  yum.repos.d

[root@cl-node03 docker_image_build]# docker build -t tinyhttpd:v0.1-2 .
Sending build context to Docker daemon  33.28kB
Step 1/5 : FROM busybox:latest
latest: Pulling from library/busybox
b71f96345d44: Pull complete 
Digest: sha256:0f354ec1728d9ff32edcd7d1b8bbdfc798277ad36120dc3dc683be44524c8b60
Status: Downloaded newer image for busybox:latest
 ---> 69593048aa3a
Step 2/5 : MAINTAINER "Beapx <bearpx@kunking.com>"
 ---> Running in 2fd0a27d6c2b
Removing intermediate container 2fd0a27d6c2b
 ---> b40c7207b65d
Step 3/5 : COPY index.html  /data/web/html/
 ---> 01c7e631375b
Step 4/5 : COPY yum.repos.d /etc/yum.repos.d/
 ---> 4c12f602fcda
Step 5/5 : ADD http://nginx.org/download/nginx-1.20.0.tar.gz  /usr/local/src/
Downloading [==================================================>]  1.061MB/1.061MB
 ---> dea83427e26d
Successfully built dea83427e26d
Successfully tagged tinyhttpd:v0.1-2

ADD URL远程文件到目录
[root@cl-node03 docker_image_build]# docker run --name tinyweb1 --rm tinyhttpd:v0.1-2 ls /usr/local/src/
nginx-1.20.0.tar.gz

ADD 本地tar.gz文件到目录
ADD nginx-1.20.1.tar.gz /usr/local/src/
[root@cl-node03 docker_image_build]# docker run --name tinyweb2 --rm tinyhttd:v0.1-4 ls /usr/local/src/
nginx-1.20.1

2.6 WORKDIR

  • 用于为Dockerfile中所有的RUN、 CMD、 ENTRYPOINT、 COPY、 ADD指令设定工作目录
  • 语法:WORKDIR <dirpath> 
  • 在Dockerfile文件中, WORKDIR指令可出现多次,其路径也可以为相对路径,是相对此前一个WORKDIR指令指定的路径。
  • WORKDIR也可调用有ENV指定定义的变量
  • WORKDIR /var/log  或  WORKDIR  $STATEPATH
#ADD nginx-1.20.1.tar.gz /usr/local/src/
WORKDIR /usr/local/
ADD nginx-1.20.1.tar.gz ./src/

2.7 VOLUME

  • 用于在image中创建一个挂载点目录,以挂载 Docker Host上的卷或其他容器上的卷 
  • 语法: VOLUME <mountpoint>  或 VOLUME ["<mountpoint>"]
  • 如果挂载点目录路径下此前有文件存在,docker run命令会在卷挂载完成后将此前的所有文件复制到新挂载的卷中
  • VOLUME /data/mysql

2.8 EXPOSE

  • 用于为容器打开指定要监听的端口以实现与外部通信
  • 语法: EXPOSE <port>[/<protocol>] [<port>[/<protocol>] ...]
  • EXPOSE 11211/tcp 11211/udp
[root@k8s-node33 docker_build]# cat Dockerfile 
FROM busybox:latest
MAINTAINER "Beapx <bearpx@kunking.com>"
COPY index.html  /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
ADD http://nginx.org/download/nginx-1.20.0.tar.gz  /usr/local/src/
VOLUME /data/mysql/
EXPOSE 80/tcp

[root@k8s-node33 docker_build]# docker build -t tinyhttpd:v0.3 .

 

[root@k8s-node33 docker_build]# docker run --name tinyweb1 --rm tinyhttpd:v0.3 /bin/httpd -f -h /data/web/html/

[root@k8s-node33 ~]# docker ps 
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS          PORTS     NAMES
8881d720b5c7   tinyhttpd:v0.3   "/bin/httpd -f -h /d…"   14 seconds ago   Up 13 seconds   80/tcp    tinyweb1

[root@k8s-node33 ~]# docker exec -it 8881d720b5c7 /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # exit
[root@k8s-node33 ~]# curl 172.17.0.2
<h1>Busybox httpd server.</h1>

 

[root@k8s-node33 docker_build]# docker run --name tinyweb2  -P --rm tinyhttpd:v0.3 /bin/httpd -f -h /data/web/html/

[root@k8s-node33 ~]# docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS          PORTS                   NAMES
d51105572f60   tinyhttpd:v0.3   "/bin/httpd -f -h /d…"   11 seconds ago   Up 10 seconds   0.0.0.0:32768->80/tcp   tinyweb2
8881d720b5c7   tinyhttpd:v0.3   "/bin/httpd -f -h /d…"   4 minutes ago    Up 4 minutes    80/tcp                  tinyweb1
[root@k8s-node33 ~]# docker port tinyweb2
80/tcp -> 0.0.0.0:32768

2.9 ENV

  • 用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其他指令(ENV、ADD、COPY等)调用
  • 调用格式为 $variable_name  或 ${variable_name}
  • 语法:  ENV <key> <value>   或  ENV  <key>=<value> 
  • 第一种格式: <key>之后的所有内容均被视作<value>的组成部分,一次只能设置一个变量
  • 第二种格式:一次设置多个变量, 变量为"<key>=<value>"的键值对。
  • 如果<value>中包含空格,可以以反斜线(\)进行转义,也可对<value>加引号进行标识;反斜线也用于续行。
  • 定义多个变量时,建议使用第二种格式,以便在同一层中完成所有功能
[root@k8s-node33 docker_build]# cat Dockerfile 
FROM busybox:latest
MAINTAINER "Beapx <bearpx@kunking.com>"
ENV DOC_ROOT=/data/web/html/ \
    WEB_SERVER_PACKAGE="nginx-1.15.2"

COPY index.html  ${DOC_ROOT:-/data/web/html/}
COPY yum.repos.d /etc/yum.repos.d/

#ADD http://nginx.org/download/nginx-1.20.0.tar.gz  /usr/local/src/
WORKDIR /usr/local/
ADD ${WEB_SERVER_PACKAGE}.tar.gz ./src/

VOLUME /data/mysql/
EXPOSE 80/tcp

[root@k8s-node33 docker_build]# docker run --name web04 --rm -P tinyhttpd:v0.4 printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=c7ba5d8e6959
DOC_ROOT=/data/web/html/
WEB_SERVER_PACKAGE=nginx-1.15.2
HOME=/root

[root@k8s-node33 docker_build]# docker run --name web04 --rm -P -e WEB_SERVER_PACKAGE="nginx-1.15.1" tinyhttpd:v0.4 printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=3651228a9e94
WEB_SERVER_PACKAGE=nginx-1.15.1
DOC_ROOT=/data/web/html/
HOME=/root

[root@k8s-node33 docker_build]# docker run --name web04 --rm -P -e WEB_SERVER_PACKAGE="nginx-1.20.0" tinyhttpd:v0.4 ls /usr/local/src
nginx-1.15.2

2.10 RUN

  • 指定 docker build 过程中运行的程序,可以是任何命令
  • 语法: 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特性的话,可替换为 RUN ["/bin/sh","-c","<executable>", "<param1>"]
  • json数组中,要使用 双引号 
  • 示例: RUN yum -y install epel-release && yum makecache && yum install nginx
[root@k8s-node33 docker_build]# cat Dockerfile
FROM busybox:latest
MAINTAINER "Beapx <bearpx@kunking.com>"
ENV DOC_ROOT=/data/web/html/ \
    WEB_SERVER_PACKAGE="nginx-1.15.2.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_PACKAGE}  /usr/local/src/
WORKDIR /usr/local/
#ADD ${WEB_SERVER_PACKAGE}.tar.gz ./src/

VOLUME /data/mysql/
EXPOSE 80/tcp
RUN cd /usr/local/src && \
    mv nginx-* webserver

[root@k8s-node33 docker_build]# docker build -t tinyhttpd:v0.5 .

[root@k8s-node33 docker_build]# docker run --name web05 --rm -P tinyhttpd:v0.5 ls /usr/local/src
webserver

2.11 CMD

  • 类似于RUN指令,CMD指令可用于运行任何命令或应用程序,二者运行时间点不同不过,
  • RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像文件启动一个容器时
  • CMD指令的首要目的是为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止
  • CMD指定的命令可以被docker run的命令行选项所覆盖
  • 在Dockerfile可以存在多个CMD指令,但仅最后一个会生效
  • 语法: CMD <command> 或 CMD ["execuatable", "<param1>", "<param2>"] 或 CMD ["<param1>", "<param2>"]
  • 前两种语法格式的意义同RUN, 第三种用于为ENTRYPOINT指令提供默认参数
  • RUN 一个软件需要的前置包的安装命令, CMD 软件安装完成后的启动命令
[root@k8s-node33 docker_build]# cat Dockerfile
FROM busybox:latest
LABEL maintainer="Beapx <bearpx@kunking.com>" app=httpd
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
    echo '<h1>Busybox httpd server!!!</h1>' > ${WEB_DOC_ROOT}/index.html

CMD /bin/httpd -f -h ${WEB_DOC_ROOT}

[root@k8s-node33 docker_build]# docker inspect image tinyhttpd:v0.6
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "WEB_DOC_ROOT=/data/web/html/"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "/bin/httpd -f -h ${WEB_DOC_ROOT}"
            ],

[root@k8s-node33 docker_build]# docker run --name web06 -it  --rm -P tinyhttpd:v0.6 

[root@k8s-node33 ~]# docker exec -it web06 /bin/sh
/ # ps 
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/httpd -f -h /data/web/html/
    6 root      0:00 /bin/sh
   11 root      0:00 ps

[root@k8s-node33 ~]# curl http://172.17.0.2
<h1>Busybox httpd server!!!</h1>

 

CMD格式2: CMD ["/bin/httpd", "-f", "-h ${WEB_DOC_ROOT}"]

[root@k8s-node33 docker_build]# docker build -t tinyhttpd:v0.6-1 .
[root@k8s-node33 docker_build]# docker inspect image tinyhttpd:v0.6-1

            "Cmd": [
                "/bin/httpd",
                "-f",
                "-h ${WEB_DOC_ROOT}"
            ],
[root@k8s-node33 docker_build]# docker run --name web06-1 -it  --rm -P tinyhttpd:v0.6-1 
httpd: can't change directory to ' ${WEB_DOC_ROOT}': No such file or directory

CMD ["/bin/httpd", "-f", "-h /data/web/html/"]
[root@k8s-node33 docker_build]# docker run --name web06-8 -it  -P tinyhttpd:v0.6-8
httpd: can't change directory to ' /data/web/html/': No such file or directory

  

CMD格式3: CMD ["/bin/sh","-c","/bin/httpd", "-f", "-h ${WEB_DOC_ROOT}"]  报错

[root@k8s-node33 docker_build]# docker inspect image tinyhttpd:v0.6-5
            "Cmd": [
                "/bin/sh",
                "-c",
                "/bin/httpd",
                "-f",
                "-h ${WEB_DOC_ROOT}"
            ],


## CMD ["/bin/sh","-c","/bin/httpd -f -h ${WEB_DOC_ROOT}"]  成功
[root@k8s-node33 docker_build]# docker build -t tinyhttpd:v0.6-6 .
[root@k8s-node33 docker_build]# docker inspect image tinyhttpd:v0.6-6
            "Cmd": [
                "/bin/sh",
                "-c",
                "/bin/httpd -f -h ${WEB_DOC_ROOT}"
            ],

[root@k8s-node33 docker_build]# docker run --name web06-6 -it  -P tinyhttpd:v0.6-6

 

2.12 ENTRYPOINT

  • 类似于CMD指令的功能, 用于为容器指定默认运行程序, 从而使得容器像一个单独的可执行程序。
  • 与CMD不同的是, 由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖
  • 而且,这些命令参数会被当做参数传递给ENTRYPOINT指定程序
  • docker run 命令的 --entrypoint 选项的参数可覆盖ENTRYPOINT指令指定的程序 
  • 语法: ENTRYPOINT <command> 或 ENTRYPOINT ["execuatable", "<param1>", "<param2>"] 
  • docker run 命令传入的命令参数会覆盖CMD指令的内容并附加到ENTRYPOINT指令最后作为其参数使用
  • Dockerfile 文件可以存在多个ENTRYPOINT指令,但仅有最后一个生效
[root@k8s-node33 docker_build]#  cat Dockerfile
FROM busybox:latest
LABEL maintainer="Beapx <bearpx@kunking.com>" app=httpd
ENV WEB_DOC_ROOT="/data/web/html/"
RUN mkdir -p $WEB_DOC_ROOT && \
    echo '<h1>ENTRYPOINT:  Busybox httpd server!!!</h1>' > ${WEB_DOC_ROOT}/index.html

ENTRYPOINT /bin/httpd -f -h ${WEB_DOC_ROOT}
[root@k8s-node33 docker_build]# docker inspect image tinyhttpd:v0.7
            "Entrypoint": [
                "/bin/sh",
                "-c",
                "/bin/httpd -f -h ${WEB_DOC_ROOT}"
            ],

[root@k8s-node33 docker_build]# docker run --name web07 -it  -P tinyhttpd:v0.7  正确

[root@k8s-node33 docker_build]# docker run --name web07-1 -it --rm  -P --entrypoint="ls /data" tinyhttpd:v0.7 
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "ls /data": stat ls /data: no such file or directory: unknown.

[root@k8s-node33 docker_build]# docker run --name web07-1 -it --rm  -P --entrypoint="/bin/ls /data" tinyhttpd:v0.7 
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "/bin/ls /data": stat /bin/ls /data: no such file or directory: unknown.

  

格式2: 错误
CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
ENTRYPOINT /bin/sh -c

[root@k8s-node33 docker_build]# docker inspect image tinyhttpd:v0.7-1
            "Cmd": [
                "/bin/sh",
                "-c",
                "/bin/httpd -f -h ${WEB_DOC_ROOT}"
            ],
            "Image": "sha256:094416742163d7eaaf75709e80b5c05e3ab39931d388bfc61088889f6c97a2e3",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/bin/sh",
                "-c",
                "/bin/sh -c"
            ],
[root@k8s-node33 docker_build]# docker run --name web07-1 -it  -P tinyhttpd:v0.7-1 
/bin/sh: -c requires an argument

格式2-1: 正确,但 ENTRYPOINT没有使用
CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
ENTRYPOINT 
[root@k8s-node33 docker_build]# docker inspect image tinyhttpd:v0.7-1
            "Cmd": [
                "/bin/sh",
                "-c",
                "/bin/httpd -f -h ${WEB_DOC_ROOT}"
            ],
            "Image": "sha256:094416742163d7eaaf75709e80b5c05e3ab39931d388bfc61088889f6c97a2e3",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,

[root@k8s-node33 docker_build]# docker run --name web07-2 -it  -P tinyhttpd:v0.7-2

  

格式3: 正确
CMD ["/bin/httpd", "-f",  "-h ${WEB_DOC_ROOT}"]
ENTRYPOINT ["/bin/sh", "-c"]
[root@k8s-node33 docker_build]# docker inspect image tinyhttpd:v0.7-5
            "Cmd": [
                "/bin/httpd",
                "-f",
                "-h ${WEB_DOC_ROOT}"
            ],
            "Image": "sha256:c3bd054af598a56fd8f787ae533a3f23b17b40bc08b752054cd4645ac375dcd6",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/bin/sh",
                "-c"
            ],

[root@k8s-node33 docker_build]# docker run --name web07-51 -it  -P tinyhttpd:v0.7-5 "ls /data"
web

  

格式4: 错误

[root@k8s-node33 docker_build]# cat Dockerfile
FROM nginx
LABEL maintainer="Beapx <bearpx@kunking.com>"
ENV NGX_DOC_ROOT="/data/web/html/"
ADD entrypoint.sh /bin/                        # 不要少了/
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]   # 不要少了;
ENTRYPOINT ['/bin/entrypoint.sh']

[root@k8s-node33 docker_build]# chmod +x entrypoint.sh 
[root@k8s-node33 docker_build]# 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@k8s-node33 docker_build]# docker run --name myweb01 -it --rm  -P myweb:v0.1
/usr/sbin/nginx: 1: /usr/sbin/nginx: [/bin/entrypoint.sh]: not found

  

格式4-1: 正确

[root@k8s-node33 docker_build]# cat Dockerfile
FROM nginx
LABEL maintainer="Beapx <bearpx@kunking.com>"
ENV NGX_DOC_ROOT="/data/web/html/"

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

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]

[root@k8s-node33 docker_build]# docker build -t myweb:v0.8 .

[root@k8s-node33 docker_build]# docker run --name myweb08-1 -it  -P -e "PORT=8080" myweb:v0.8

[root@k8s-node33 ~]# docker exec -it 69050922a167 /bin/sh
# printenv
HOSTNAME=69050922a167
PORT=8080
HOME=/root
PKG_RELEASE=1~buster
TERM=xterm
NGINX_VERSION=1.21.3
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NJS_VERSION=0.6.2
NGX_DOC_ROOT=/data/web/html/
PWD=/

[root@k8s-node33 ~]# curl http://172.17.0.3:8080
<h1>Busybox httpd server.</h1>

172.17.0.1 - - [07/Nov/2021:10:51:28 +0000] "GET / HTTP/1.1" 200 31 "-" "curl/7.61.1" "-"

2.13 USER

  • 用于指定运行image时或运行Dockerfile中任何RUN、CMD或ENTRYPOINT指令指定的程序时的用户名或UUID
  • 默认情况下,container的运行身份为root用户
  • 语法: USER <UID> | <UserName>
  • <UID>可以为任意数字,但必须为/etc/passwd中某用户的有效UID,否则,docker run将运行失败。

2.14 HEALTHCHECK

  • The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working.
  • 语法: HEALTHCHECK [OPTIONS] CMD 或  HEALTHCHECK NONE
  • The options that can apper before CMD: 
  • --interval=DURATION(default:30s)
  • --timeout=DURATION(default:30s)
  • --start-period=DURATION(default:0s)
  • --retries=N(default=3)
  • The command's exit status indicates the health status of the container.
  • 0: success - the container is healthy and ready for use
  • 1: unhealthy - the container is not working correctly
  • 2: reserved - do not use this exit code
  • 示例: HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost || exit 1
FROM nginx
LABEL maintainer="Beapx <bearpx@kunking.com>"

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

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

EXPOSE 80/tcp

HEALTHCHECK --start-period=3s CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT:80}/  # 容器中必须有wget命令,不然不会进行健康检查

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]

 

[root@k8s-node33 ~]# docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED          STATUS                            PORTS                   NAMES
e74fa197d265   myweb:v0.9   "/bin/entrypoint.sh …"   7 seconds ago    Up 6 seconds (health: starting)   0.0.0.0:32783->80/tcp   myweb09


[root@k8s-node33 ~]# docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED          STATUS                     PORTS                   NAMES
e74fa197d265   myweb:v0.9   "/bin/entrypoint.sh …"   7 minutes ago    Up 2 minutes (unhealthy)   0.0.0.0:32784->80/tcp   myweb09

  

[root@k8s-node33 docker_build]# docker build -t myweb:v0.12 .
[root@k8s-node33 docker_build]# cat Dockerfile
FROM nginx
LABEL maintainer="Beapx <bearpx@kunking.com>"

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

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

EXPOSE 80/tcp

HEALTHCHECK --start-period=3s CMD curl http://${IP:-0.0.0.0}:${IP:-80}/

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]

  

[root@k8s-node33 docker_build]# docker run --name myweb12 -it  -P   myweb:v0.12

127.0.0.1 - - [07/Nov/2021:11:28:04 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.64.0" "-"
127.0.0.1 - - [07/Nov/2021:11:28:35 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.64.0" "-"
127.0.0.1 - - [07/Nov/2021:11:29:05 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.64.0" "-"
127.0.0.1 - - [07/Nov/2021:11:29:35 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.64.0" "-"

[root@k8s-node33 ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS                      PORTS                   NAMES
5aff35281f68   myweb:v0.12   "/bin/entrypoint.sh …"   39 seconds ago   Up 38 seconds (healthy)     0.0.0.0:32787->80/tcp   myweb12

2.15 SHELL

  • The SHELL instruction allows the default shell used for the shell form of commands to be overridden.
  • The default shell on Linux is ["/bin/sh","-c"]。on Windows is ["cmd", "/S", "/C"]。
  • 语法: SHELL ["executable", "parameters"]
  • SHELL 可以出现多次,但会覆盖上一个SHELL指令

2.16 STOPSIGNAL

  • The STOPSIGNAL instruction sets the system call signal that will be sent to the container to exit。
  • This signal can be a valid unsigned number that matches a position in the kernel syscall table.
  • 语法: STOPSIGNAL signal

2.17 ARG

  • The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build command using the --build-arg <varname>=<value> flag。
  • If a user specifies a build argument that was not defined in the Dockerfile,the build outputs a warning。
  • 语法: ARG <name>[=<default value>]
  • 示例: ARG version=1.16    ARG user=bearpx
[root@k8s-node33 docker_build]# cat Dockerfile
FROM nginx:${nginx_tag}

ARG nginx_tag="1.20.0-alpine"

LABEL maintainer="Beapx <bearpx@kunking.com>"

[root@k8s-node33 docker_build]# docker build -t myweb:v0.13 .
Sending build context to Docker daemon  2.133MB
Step 1/10 : FROM nginx:${nginx_tag}
invalid reference format

[root@k8s-node33 docker_build]# cat Dockerfile
FROM nginx

ARG author="Beapx <bearpx@kunking.com>"

LABEL maintainer="${author}"

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

 

2.18 ONBUILD

  • 用于在Dockerfile中定义一个触发器
  • Dockerfile用于build映像文件,此映像文件亦可作为 base image被另一个Dockerfile 用作FROM指令的参数,并以之构建新的映像文件
  • 在后面的Dockerfile中的FROM指令在build过程中被执行时, 将会触发创建其base image 的Dockerfile的ONBUILD指令定义的触发器
  • 语法: ONBUILD <INSTRUCTION>
  • 尽管任何指令都可注册成为触发器指令,但ONBUILD不能自我嵌套,且不会触发FROM和MAINTAINER指令
  • 使用包含ONBUILD指令的Dockerfile构建的镜像应该使用特殊的标签,如nginx:v2.0-onbuild
  • 在ONBUILD指令中使用ADD或COPY指令应该小心,新构建过程的上下文在缺少指定的源文件时会失败
[root@k8s-node33 docker_build]# cat Dockerfile
FROM nginx

ARG author="Beapx <bearpx@kunking.com>"

LABEL maintainer="${author}"

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

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

EXPOSE 80/tcp

HEALTHCHECK --start-period=3s CMD curl http://${IP:-0.0.0.0}:${IP:-80}/

ONBUILD COPY yum.repos.d /etc/yum.repos.d/

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]

[root@k8s-node33 docker_build]# docker build -t myweb:v1.0 .

  

[root@k8s-node33 myweb]# cat Dockerfile 
FROM myweb:v1.0
RUN mkdir /tmp/test

[root@k8s-node33 myweb]# docker build -t myweb:v1.1 .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM myweb:v1.0
# Executing 1 build trigger
COPY failed: stat /var/lib/docker/tmp/docker-builder940814215/yum.repos.d: no such file or directory

[root@k8s-node33 myweb]# cp -a ../docker_build/yum.repos.d/ .
[root@k8s-node33 myweb]# ls
Dockerfile  yum.repos.d
[root@k8s-node33 myweb]# docker build -t myweb:v1.1 .
Sending build context to Docker daemon  36.35kB
Step 1/2 : FROM myweb:v1.0
# Executing 1 build trigger
 ---> e69ca7fa8109
Step 2/2 : RUN mkdir /tmp/test
 ---> Running in 916bf934e812
Removing intermediate container 916bf934e812
 ---> ba05adead111
Successfully built ba05adead111
Successfully tagged myweb:v1.1

  

[root@k8s-node33 docker_build]# docker history myweb:v1.1
IMAGE          CREATED        CREATED BY                                       SIZE      COMMENT
ba05adead111   26 hours ago   /bin/sh -c mkdir   /tmp/test                     0B        
e69ca7fa8109   26 hours ago   /bin/sh -c #(nop)  COPY dir:8cbe9eff635e171f9…   17.8kB    
dd6fa0373f98   27 hours ago   /bin/sh -c #(nop)  ENTRYPOINT ["/bin/entrypo…    0B   
......

2.19 docker build命令

[root@component ~]# docker build -h
Flag shorthand -h has been deprecated, please use --help

Usage:  docker build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile

Options:
      --add-host list           Add a custom host-to-IP mapping (host:ip)
      --build-arg list          Set build-time variables
      --cache-from strings      Images to consider as cache sources
      --cgroup-parent string    Optional parent cgroup for the container
      --compress                Compress the build context using gzip
      --cpu-period int          Limit the CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int           Limit the CPU CFS (Completely Fair Scheduler) quota
  -c, --cpu-shares int          CPU shares (relative weight)
      --cpuset-cpus string      CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string      MEMs in which to allow execution (0-3, 0,1)
      --disable-content-trust   Skip image verification (default true)
  -f, --file string             Name of the Dockerfile (Default is 'PATH/Dockerfile')
      --force-rm                Always remove intermediate containers
      --iidfile string          Write the image ID to the file
      --isolation string        Container isolation technology
      --label list              Set metadata for an image
  -m, --memory bytes            Memory limit
      --memory-swap bytes       Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --network string          Set the networking mode for the RUN instructions during build (default
                                "default")
      --no-cache                Do not use cache when building the image
      --pull                    Always attempt to pull a newer version of the image
  -q, --quiet                   Suppress the build output and print image ID on success
      --rm                      Remove intermediate containers after a successful build (default true)
      --security-opt strings    Security options
      --shm-size bytes          Size of /dev/shm
  -t, --tag list                Name and optionally a tag in the 'name:tag' format
      --target string           Set the target build stage to build.
      --ulimit ulimit           Ulimit options (default [])