zoukankan      html  css  js  c++  java
  • docker(四)--Dockerfile

    镜像制作
    1,基于容器制作
    2,dockerfile


    docker 语法格式

    • # comment 注释信息
    • INSTRUCTION arguments 指令与参数,通常指令都是大写

    docker是自上而下顺序执行的,第一个非注释行必须是'FROM'指令,基于哪个基础镜像来做的

    Dockerfile
    1,需要有一个专用工作目录
    2,dockerfile放在这个工作目录下,且文件名首字母大写
    3,dockerfile如果要打包其他文件到镜像,这些文件的路径必须是当前工作目录或下级子目录,不能是父目录
    4,dockerfile支持制作一个隐藏文件.dockeringore,这个文件中可以写入文件路径,在打包时,所有写在.dockeringore中的文件都不包含进去。 例如要打包一个目录下的文件,但不包含其中某3个文件,可以将这3个文件的路径写入.dockeringore。那么.dockeringore本身以及里面包含的文件,都不会被打包进去。

    变量

    变量引用:$variable_name  ${variable_name}
    ${variable:-word}   如果变量没设置或值为空,就使用word字串,否则就返回变量值。用得较多

    [root@abao ~]# echo ${NAME:-lily}
    lily
    [root@abao ~]# NAME=jerry
    [root@abao ~]# echo ${NAME:-lily}
    jerry

    ${variable:+word} 变量有值就显示word, 没值就没

    [root@abao ~]# NAME=jerry
    [root@abao ~]# echo ${NAME:+tom}
    tom
    [root@abao ~]# unset NAME
    [root@abao ~]# echo ${NAME:+tom}

    Dockerfile常用指令 

    FROM  最重要的一个指令,且必须为Dockerfile文件开篇的第一个非注释行,用于指定基准镜像,后续的指令运行于基准镜像提供的运行环境。
    基准镜像可以是任何可用镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,当其不存在时,则从Docker Hub上拉取
    语法:
    - FROM <repository>[:<tag>]或
    - FROM <repository>@<digest> # <repository>:指定作为base image的名称,digest指定hash码

    MAINTAINER (可选,已废弃被LABLE代替)    用于让Dockerfile制作者提供本人的信息

    LABLE  为镜像指定各种元数据。   语法:LABEL <key>=<value> <key>=<value> <key>=<value> ... 键值数据

    COPY   从宿主机把文件复制到目标镜像中
    语法:
    - COPY <src> ..<des> 或
    - COPY ["<src>",..."<dest>"]
    <src>: 要复制的源文件或目录,支持使用通配符(一般是当前工作目录)
    <dest>: 目标路径,即正在创建的image的文件系统路径,建议为<dest>使用绝对路径,否则以WORKDIR为其起始路径
    注:在路径中有空白字符时,通常使用第二种格式

    文件复制准则
    - <src> 必须是build上下文中的路径,不能是其父目录的文件
    - <src> 如果是目录,<src>目录自身不会被复制,其内部文件或子目录都会被复制。 (目录自身不会被复制,如cp -r tmp/* /tmp)
    - 如果指定了多个<src>,或在<src>中使用了通配符,则<dest>必须是一个目录,且必须以/结尾,不加会报错
    - 如果<dest>事先不存在,它将会自动创建

    COPY index.html /data/web/html/      # index.html一定要在当前目录下,或在子目录下
    COPY yum.repos.d /etc/yum.repos.d/     #复制yum.repos.d目录只是复制它下面的内容,所以要写明目标目录名

    Dockerfile:

    # Description: test image
    FROM busybox:latest
    #MAINTAINER "abao <abao@163.com>"
    LABEL maintainer="abao <abao@163.com>"
    COPY index.html /data/web/html/

    # docker build -t testhttpd:v1.0 ./
    # ls
    Dockerfile index.html
    # docker run --name tinyweb1 --rm tinyhttpd:v0.1 cat /data/web/html/index.html
    <h1>hello, Busybox httpd server image.</h1>

    ADD    类似于COPY指令,ADD支持使用tar文件和URL路径
    语法:
    ADD <src> ...<dest> 或
    ADD ["<src>",.."<dest>"]

    - 同COPY指令
    - <src>为URL且<dest>不以/结尾,则<src>指定的文件将被下载并被创建为<dest>;如果<dest>以/结尾,则URL指定的文件将被下载并保存到<dest>/目录下
    - <src>是一个本地压缩格式tar文件,它将被展开为一个目录,类似于"tar -x"命令;  但是,通过URL获取的tar文件不会自动展开 
    - <src>有多个,或使用了通配符,则<dest>必须是一个以/结尾的目录路径,如果<dest>不以/结尾,则其被视作一个普通文件,<src>的内容被直接写入到<dest>;

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

      语法: WORKDIR <dirpath>

    volume  用于在image中创建一个挂载点目录,用来挂载Docker host上的卷或其它容器上的卷
    语法: VOLUME <mountpoint> 或 VOLUME |”<mountpoint>"
    如果挂载点目录路径下此前在文件存在,docker run命令会在卷挂载完成后将此前所有文件复制到新挂载的卷中
    卷有两种格式:绑定挂载卷和docker管理卷,dockerfile中只能用docker管理的卷,即指定容器中的路径,而不能指定宿主机的目录

    VOLUME /data/mysql/
    # docker build -t tinyhttpd:v0.5 ./
    # docker run --name tinyweb1 --rm tinyhttpd:v0.5 sleep 100
    # docker inspect tinyweb1
            "Mounts": [
                {
                    "Type": "volume",
                    "Name": "a08c5c5c1c4779e77a97682cd6309fbc67e61ece448965354eea28556b7dae29",
                    "Source": "/var/lib/docker/volumes/a08c5c5c1c4779e77a97682cd6309fbc67e61ece448965354eea28556b7dae29/_data",
                    "Destination": "/data/mysql",

      

    EXPOSE  待暴露端口,用于为容器打开指定要监听的端口以实现与外部通信 

    (只能指定容器暴露的端口,再随机绑定宿主机的端口,不能指定宿主机绑定的端口)
    语法: 
        EXPOSE <port>[/<protocol>][<port>[/<protocol>]...]
             <protocol> 用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议
             EXPOSE指令可一次指定多个端口,例如EXPOSE 112/udp 112/tcp

     注意:写在dockerfile中的端口暴露并不会直接暴露,使用docker run中的-P选项时,不用指定,会自动读取镜像中要暴露那个端口

    EXPOSE 80/tcp
    # docker build -t tinyhttpd:v0.6 ./
    # docker run --name tinyweb1 --rm tinyhttpd:v0.6 /bin/httpd -f -h /data/web/html
    # docker inspect tinyweb1   查看容器的ip
    # curl 172.17.0.3
    <h1>hello, Busybox httpd server image.</h1>
    # docker port tinyweb1   #实际查询没有暴露端口
    # docker kill tinyweb1
    tinyweb1
    # docker run --name tinyweb1 --rm -P tinyhttpd:v0.6 /bin/httpd -f -h /data/web/html 
    # docker port tinyweb1
    80/tcp -> 0.0.0.0:32769
    可以在外部访问宿主机:32769 

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

    语法:
    ENV <key> <value>    #一次只能设置一个变量,<key>之后所有内容均会被视作其<value>的组成部分
    ENV <key>=<value>...   # 一次可设置多个变量,每个变量为一个"<k>=<v>"的键值对,如果<value>中有空格,可以用反斜线转义,也可用<value>引号进行标识;另外,反斜线也可用于续行。当定义多个变量时,建议使用这种方式,以便在同一层中完成所有功能

    例如:

    ENV DOC_ROOT=/data/web/html/ 
        WEB_SERVER_PACKAGE="nginx-1.17.8"
    COPY index.html ${DOC_ROOT:-/data/web/html/}
    WORKDIR /usr/local/src/
    ADD ${WEB_SERVER_PACKAGE}.tar.gz ./
    
    # docker build -t tinyhttpd:v0.7 ./
    # docker run --name tinyweb1 --rm tinyhttpd:v0.7 ls /usr/local/src/
    nginx-1.17.8
    # docker run --name tinyweb1 --rm tinyhttpd:v0.7 cat /data/web/html/index.html
    <h1>hello, Busybox httpd server image.</h1>
    # docker run --name tinyweb1 --rm tinyhttpd:v0.7 printenv
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    HOSTNAME=1c99b2e89674
    DOC_ROOT=/data/web/html/
    WEB_SERVER_PACKAGE=nginx-1.17.8
    HOME=/root

     在docker run时 通过-e 选项 也可指定变量

    # docker run --name tinyweb1 --rm -e WEB_SERVER_PACKAGE=nginx-1.14.0 tinyhttpd:v0.7 printenv
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    HOSTNAME=e13da61e21b2
    WEB_SERVER_PACKAGE=nginx-1.14.0
    DOC_ROOT=/data/web/html/
    HOME=/root
    # docker run --name tinyweb1 --rm -e WEB_SERVER_PACKAGE=nginx-1.14.0 tinyhttpd:v0.7 ls /usr/local/src/
    nginx-1.17.8
    #可以看到docker run时可以修改环境变量的值,但是并不会改变docker build过程

     RUN    用于 docker build 过程中运行的命令

    ENV DOC_ROOT=/data/web/html/ 
        WEB_SERVER_PACKAGE="nginx-1.17.8.tar.gz"
    ADD http://nginx.org/download/${WEB_SERVER_PACKAGE} /usr/local/src/
    WORKDIR /usr/local/src/
    
    RUN cd /usr/local/src && 
        tar -xf ${WEB_SERVER_PACKAGE} && 
        mv nginx-1.17.8 webserver
    
    # docker build -t tinyhttpd:v0.8 ./
    # docker run --name tinyweb1 --rm -it tinyhttpd:v0.8
    /usr/local/src # ls
    nginx-1.17.8.tar.gz  webserver

    Syntax:

    • RUN <command> 或
    • RUN ["<executable>","<param1>","<param2>"]    #注意要使用双引号,单引号可能会出错

    - 第一种格式,<command>通常是一个shell命令,且以"/bin/sh -c"来运行它,当作shell子进程来运行,这意味此进程在容器的PID不为1,不能接收Unix信号,因此,当使用docker stop <container>命令停止容器时,此进程接收不到SIGTERM信号。

    - 第二种中的参数是一个JSON格式的数组,其中<executable>为要运行命令,后面<paramN>为传递给命令的选项或参数;然而,命令不会以"/bin/sh -c"来发起,也就是直接由内核来创建,因此常见的shell操作如变量替换以及通配符(?,*等)替换将不会进行; 不过,如果想使用shell来操作,可以使用以下格式:RUN ["/bin/bash","-c","<exectuable>","<param1>"]

    CMD   用于定义把镜像启动为容器时(docker run) 默认运行的命令

    -  类似于RUN指令,CMD指令也可用于运行任何命令或应用程序,不过,二者的运行时间点不同,RUN指令运行于映像文件构建过程中,而CMD指令运行基于Dockerfile构建出新映像文件 启动一个容器时

    -  CMD指令的首要目的在于为启动容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过,CMD指定的命令其可以被docker run的命令选项所覆盖
    - 在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效
    语法:

    • CMD <command> #  自动运行为shell子进程,最大的坏处是id不为1,无法使用docker stop去停止,因为它接收不到信号,接信号都是进程号为1的进程,因为它是一个超管进程,可以让它为1
    • CMD ["<executable>","<param1>","<param2>"]     #  直接启动为用户id为1的进程,可以接收处理shell的信号
    • CMD ["<param1>","<param2>"]   # 用于 ENTRYPOINT 指令提供默认参数

    测试第一种方法:

    FROM busybox
    LABEL maintainer="abao <abao@163.com>" app="httpd"
    
    ENV WEB_DOCROOT="/data/web/html/"
    
    RUN mkdir -p ${WEB_DOCROOT} && 
        echo "<h1> Busybox httpd server.</h1>" > ${WEB_DOCROOT}/index.html
    
    CMD /bin/httpd -f -h ${WEB_DOCROOT}
    #启动容器时,应该是作为shell的子进程来运行,pid不为1
    
    #创建镜像
     docker build -t tinyhttpd:v1.0 ./
    # 查看镜像 
    docker image inspect tinyhttpd:v1.0
            "Cmd": [
                "/bin/sh",    #可以看到默认会以"/bin/sh -c"来运行它
                "-c",
                "/bin/httpd -f -h ${WEB_DOCROOT}"
            ],
    # 启动容器
      docker run --name tinyweb1 -it --rm -P  tinyhttpd:v1.0
    没有进入交互式,# 镜像中定义默认运行的程序是httpd,是shell的子进程,不是shell,没有交互式接口
    
    # 使用exec进入交互式
    ]# docker exec -it tinyweb1 /bin/sh
    / # ps
    PID   USER     TIME  COMMAND
        1 root      0:00 /bin/httpd -f -h /data/web/html/  # 这里id为1是因为默认执行了exec的替换,为了确保容器能自动接收unix的信号,执行docker stop时能停止,执行docker kill时能杀掉
        6 root      0:00 /bin/sh
       11 root      0:00 ps
    / # printenv
    HOSTNAME=5b27cc8a100f
    SHLVL=1
    HOME=/root
    TERM=xterm
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    WEB_DOCROOT=/data/web/html/
    PWD=/
    / # 

    第二种方式:

    CMD ["/bin/httpd","-f","-h ${WEB_DOCROOT}"]
    
    #制作镜像
    docker build -t tinyhttpd:v1.1 ./
    # 查看镜像
    docker image inspect tinyhttpd:v1.1
                "Cmd": [
                    "/bin/httpd",
                    "-f",
                    "-h ${WEB_DOCROOT}"
                ],
    # 启动容器
     docker run --name tinyweb1 -it --rm -P  tinyhttpd:v1.1
    httpd: can't change directory to ' ${WEB_DOCROOT}': No such file or directory
    #会报错,因为程序不会运行为shell子进程,而变量是为shell变量,所以无法识别

    ENTRYPOINT

    # docker run --name tinyweb2 -it --rm -P tinyhttpd:v1.2 ls /data/web/html    
    index.html
    # docker run --name tinyweb2 -it --rm -P tinyhttpd:v1.2 httpd -f -h /data/web/html/
    # 在dockerfile中指定的默认要运行的程序是httpd,但是docker run时可以自己指定命令(ls /data/web/html和httpd ...等,覆盖镜像中默认要运行的命令

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

    Syntax:

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

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

    FROM busybox
    LABEL maintainer="abao <abao@163.com>" app="httpd"
    
    ENV WEB_DOCROOT="/data/web/html/"
    
    RUN mkdir -p ${WEB_DOCROOT} && 
        echo "<h1> Busybox httpd server.</h1>" > ${WEB_DOCROOT}/index.html
    
    ENTRYPOINT /bin/httpd -f -h ${WEB_DOCROOT}
    
    构建镜像并启动容器,测试:
    docker run --name tinyweb2 -it --rm -P tinyhttpd:v1.3 ls /data/web/html
    
    #并没有执行ls,而是执行的/bin/httpd -f -h /data/web/html ls /data/web/html。 把ls...当作参数附加在命令后面

    CMD的第三种方式:

    同时有 CMD 和 ENTRYPOINT 时,CMD指定的选项会用于为ENTRYPOINT提供默认参数

    FROM busybox
    LABEL maintainer="abao <abao@163.com>" app="httpd"
    
    ENV WEB_DOCROOT="/data/web/html/"
    
    RUN mkdir -p ${WEB_DOCROOT} && 
        echo "<h1> Busybox httpd server.</h1>" > ${WEB_DOCROOT}/index.html
    
    CMD ["/bin/httpd","-f","-h ${WEB_DOCROOT}"]
    ENTRYPOINT ["/bin/sh","-c"]
    #默认会执行 /bin/sh -c /bin/httpd -f -h /data/web/html
    docker build -t tinyhttpd:v1.3 ./ docker run --name tinyweb2 -it --rm -P tinyhttpd:v1.4 "ls /data/web/html" index.html #发现执行了 ls 命令,因为CMD的参数会被当成ENTRYPOINT的默认参数,而命令行参数会被当参数传给ENTRYPOINT,所以CMD的参数被覆盖了。执行的命令是 /bin/sh -c ls /data/web/html

    配置nginx示例:

    # cat Dockerfile 
    FROM nginx:1.14-alpine
    LABEL maintainer="abao <abao@abao.163.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"]
    
    # 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 "$@" 
    
    chmod +x entrypoint.sh
    echo " <h1> New doc root for nginx.</h1>" > index.html
    
    docker build -t myweb:v0.5 ./   
    docker run --name myweb1 --rm -P  myweb:v0.5  
    docker exec -it myweb1 /bin/sh 
    / # ps -ef
    PID   USER     TIME  COMMAND
        1 root      0:00 nginx: master process /usr/sbin/nginx -g daemon off;
        8 nginx     0:00 nginx: worker process
        9 root      0:00 /bin/sh
       14 root      0:00 ps -ef
    / # cat /etc/nginx/conf.d/www.conf 
    server {
        server_name 790db97efd5a;
        listen 0.0.0.0:80;
        root /data/web/html/;
    }
    / # wget -O - -q 790db97efd5a    #访问nginx
    <h1> New doc root for nginx.</h1>
    docker run时传递环境变量 docker run --name myweb1 --rm -P -e "PORT=8080" myweb:v0.5 docker exec -it myweb1 /bin/sh / # ps PID USER TIME COMMAND 1 root 0:00 nginx: master process /usr/sbin/nginx -g daemon off; #pid为1,因为entrypoint.sh中执行命令是exec 8 nginx 0:00 nginx: worker process 9 root 0:00 /bin/sh 14 root 0:00 ps / # cat /etc/nginx/conf.d/www.conf server { server_name 0a9b161911b8; listen 0.0.0.0:8080; root /data/web/html/; } / # wget -O - -q 0a9b161911b8:8080 <h1> New doc root for nginx.</h1>

     通常情况下,可以使用 entrypoint脚本把需要修改的部分,如IP,PORT,作为变量放在配置文件中,让脚本可以通过使用这些环境变量生成配置文件,在docker run时用环境变量给它传值。

    USER

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

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

    HEALTHCHECK
     不依据主进程运行与否来判断健康与否,而是检测是否真正能提供服务,使用wget或curl查看是否能加载页面。

    语法:

    HEALTHCHECK [OPTIONS] CMD command   (通过运行一个command来检查容器主进程是否健康)
    HEALTHCHECK NONE      (拒绝任何健康状态检测,包括默认的检测机制)

    OPTIONS:
    --interval=DURATION(default: 30s) #检测间隔时间
    --timeout=DURATION(default: 30s) #超时时间
    --start-period=DURATION(default: 0s) #容器启动时,可能进程服务还没初始化完成,这时去检查会是报错失败的,检测可以等待一段时间,像tomcat程序启动时可能需要10s
    --retries=N(default: 3) #重试次数

    响应结果:
    0:success
    1: unhealthy
    2: reserved 预留,自定义

    示例:
    HEALTHCHECK --interval=5m --timeout=3s
    CMD curl -f http://localhost || exit 1 

    FROM nginx:1.14-alpine
    LABEL maintainer="abao <abao@abao.163.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}/
    
    CMD ["/usr/sbin/nginx","-g","daemon off;"]
    ENTRYPOINT ["/bin/entrypoint.sh"]
    
    # docker run --name myweb1 --rm -P  -e "PORT=8080" myweb:v0.6
    127.0.0.1 - - [25/Feb/2020:03:16:53 +0000] "GET / HTTP/1.1" 200 34 "-" "Wget" "-"
    127.0.0.1 - - [25/Feb/2020:03:17:23 +0000] "GET / HTTP/1.1" 200 34 "-" "Wget" "-"
    127.0.0.1 - - [25/Feb/2020:03:17:53 +0000] "GET / HTTP/1.1" 200 34 "-" "Wget" "-"
    127.0.0.1 - - [25/Feb/2020:03:18:24 +0000] "GET / HTTP/1.1" 200 34 "-" "Wget" "-"

    SHELL    定义运行程序默认使用的shell

    语法: SHELL ["executable","parameters"]
    默认linux是["/bin/sh","-c"],windows是["cmd","/S","/C"]

    STOPSIGNAL

    进程号id 为 1 的,可以接收 docker stop 命令,从而能够停止主进程,从而停止容器。如 stop 发送的是 15,signal 是无符号整型数字(必须匹配 kernal 的 syscall table),如 9 ,也可以是 SIGNAME,如 SIGKILL
    Syntax: STOPSIGNAL signal

    ARG

     在 docker build 过程中传参数,使用  --build-arg <varname>=<value> 

    FROM nginx:1.14-alpine
    ARG author="abao <abao@163.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 wget -O - -q http://${IP:-0.0.0.0}:${PORT:-80}/
    
    CMD ["/usr/sbin/nginx","-g","daemon off;"]
    ENTRYPOINT ["/bin/entrypoint.sh"]
    # docker build --build-arg author="xiao <xiao@qq.com>" -t myweb:v0.9 ./
    # docker image inspect myweb:v0.9 |grep maintainer
                    "maintainer": "xiao <xiao@qq.com>"
                    "maintainer": "xiao <xiao@qq.com>"

     ONBUILD  用于在 Dockerfile 中定义一个触发器

    Dockerfile用于 build 镜像文件,此镜像文件可以作为 base image 被另一个 Dockerfile 用做 FROM 指令的参数,并以只构建新的镜像文件
    在后面的这个Dockerfile中的 FROM 指令在 build 过程中被执行时,将会“触发”创建其 base image 的 Dockerfile 文件中 ONBUILD 指令定义的触发器

        base image->build -> image1 -> build(这个过程中执行ONBUILD)->image2

    Syntax: ONBUILD <INSTRUCTION>

    • 尽管任何指令都可以注册成为触发器指令,但ONBUILD不能自我嵌套,且不会触发FROM和MAINTAINER 指令
    • 使用包含 ONBUILD 指令的 Dockerfile 构建的镜像应该使用特殊的标签,例如 ruby:2.0-onbuild
    • 在 ONBUILD 指令中使用 ADD 或 COPY指令应该格外小心,因为新构建过程的上下文在缺少指定原文件时会失败
  • 相关阅读:
    u3d 地形 U3d terrain
    u3d 鼠标点击位置,物体移动过去。 U3d mouse clicks position, objects move past.
    u3d 逐个点运动,路径运动。 U3d one by one, path motion.
    u3d 楼梯,圆环,椭圆,直线运动。世界坐标。点击。U3d stair, ring, ellipse, linear motion.World coordinates.Click .
    u3d 元件的克隆 Cloning of u3d components
    u3d 创建元件 预制件 U3d creates component prefabricated parts
    Unity3D 入门 游戏开发 Unity3D portal game development
    Egret 之 消除游戏 开发 PART 6 Egret elimination game development PART 6
    [BZOJ1101][POI2007]Zap
    [BZOJ2820]YY的GCD
  • 原文地址:https://www.cnblogs.com/xiaobaozi-95/p/10579991.html
Copyright © 2011-2022 走看看