天天看点

Docker - Dockerfile之ENV、ENTRYPOINT、VOLUME、ONBUILD、STOPSIGNAL指令详解

Docker - Dockerfile之ENV、ENTRYPOINT、VOLUME、ONBUILD、STOPSIGNAL指令详解

ENV

ENV指令用以定义镜像的环境变量。

格式

  • ​ENV <key>=<value> ...​

    ​。
  • ​ENV <key> <value>​

    ​。

该ENV指令将环境变量​

​<key>​

​​设置为值​

​<value>​

​。此值可以在构建阶段的所有后续指令中使用。

例如:

FROM ubuntu
ENV INDEX=index
RUN apt-get update && apt-get install -y curl && curl http://127.0.0.1:8080/$MODE && rm -rf /var/lib/apt/lists/*      

如果你要设置多个环境变量,为了美观,你可以使用​

​\​

​​来进行换行。多个环境变量也可以使用空格进行隔开,如果某个环境变量的值是由一组英文单词构成,那么你可以使用​

​""​

​将其圈起来。

例如:

ENV INDEX=index USER=root \
    TITLE="this is kaven's blog"      

ARG指令和ENV指令的作用很相似,但是每个指令存在就肯定有它的原因。这两个指令都是设置环境变量。与ENV指令不同的是,ARG指令设置的环境变量只是在镜像构建时使用,在将来容器运行时是不会存在这些环境变量的。由最终镜像创建并且运行容器时,使用ENV指令设置的环境变量将被保留,可以使用​

​docker inspect​

​​命令查看它们的值,或者使用​

​docker run --env <key> = <value>​

​命令更改它们的值。

如果仅在镜像构建过程中需要使用该环境变量,而在最终镜像中或者说由该镜像(最终镜像)创建的容器中已经不再需要该环境变量,就可以使用ARG指令,否则使用ENV指令,这样可以使得最终镜像足够干净。

作用的时机

  • ARG指令设置的环境变量是在构建镜像的时候使用(它不会保留在最终镜像中)。
  • ENV指令设置的环境变量一般是容器运行的时候使用(它会保留在最终镜像中)。

ENTRYPOINT

格式

  1. ​ENTRYPOINT ["executable", "param1", "param2"]​

    ​。
  2. ​ENTRYPOINT command param1 param2​

    ​。

ENTRYPOINT指令与CMD指令非常类似,​

​Dockerfile​

​​中也只允许有一个ENTRYPOINT指令,有多个ENTRYPOINT指令时,只会执行最后的ENTRYPOINT指令。在​

​docker run​

​​命令中使用了​

​--entrypoint​

​​选项时,会覆盖​

​Dockerfile​

​中的ENTRYPOINT指令设置的内容。

当使用了ENTRYPOINT指令时,CMD指令的性质将会发生改变:CMD指令中的内容将会以参数形式传递给ENTRYPOINT指令,如下:

FROM ubuntu
ENTRYPOINT ["rm", "docker"]
CMD ["-rf"]      

其实,它真正执行的命令将会是:

rm docker -rf      

VOLUME

VOLUME指令用于构建镜像时指定挂载点。

格式

  • ​VOLUME ["/data"]​

    ​。

容器是基于镜像创建的,容器的文件系统包括镜像的只读层+镜像上面的可写层,容器中新产生的数据都是保存在镜像上面的可写层。一旦容器删除后,这些数据就没了,除非我们人工备份下来(或者基于当前容器创建新的镜像)。能否让容器新产生的数据保存在主机上呢?这样即使容器删除了,数据在主机上还有备份,这就需要在容器中指定挂载点了 :​​Docker - Docker数据持久化​​。

通过​

​Dockerfile​

​的VOLUME指令可以在镜像中定义挂载点,这样只要通过该镜像创建的容器都有了挂载点。

通过VOLUME指令定义的挂载点,无法指定主机上对应的目录,当有新容器基于该镜像被创建时,新容器中的挂载点对应的主机目录,其实就是由Docker自动生成的数据卷的​

​_data​

​目录,由Docker自动生成的数据卷的名称一般如下图红框中的数据卷名称类似。

Docker - Dockerfile之ENV、ENTRYPOINT、VOLUME、ONBUILD、STOPSIGNAL指令详解

定义一个挂载点:

FROM java:8
VOLUME /java      

定义多个挂载点:

FROM java:8
VOLUME ["/java", "/classpath"]      

这里的​

​/java​

​​和​

​/classpath​

​​目录在容器运行时会自动生成并且挂载到主机上的某个目录(Docker维护的数据卷)。给容器挂载数据卷可以在​

​docker run​

​​命令中使用​

​-v​

​选项来实现。

[root@izoq008ryseuupz ~]# docker run -v /data --name java_8 java:8
[root@izoq008ryseuupz ~]# docker inspect java_8      
"Mounts": [
            {
                "Type": "volume",
                "Name": "cb954c7b65c7b249ef81154622bb7ebc41c07d508b139d0ab231be4500a4dcbb",
                "Source": "/var/lib/docker/volumes/cb954c7b65c7b249ef81154622bb7ebc41c07d508b139d0ab231be4500a4dcbb/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],      

ONBUILD

格式

  • ​ONBUILD <INSTRUCTION>​

    ​。

指定当该镜像作为其它新镜像的基础镜像时,所需要执行的命令。

例如,生成​

​image1​

​​镜像的​

​Dockerfile​

​如下。

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]      

当基于​

​image1​

​​镜像创建新镜像时(通过​

​FROM image1​

​​指令指定基础镜像),新镜像的​

​Dockerfile​

​​会自动执行​

​image1​

​​镜像的​

​Dockerfile​

​​中ONBUILD指令指定的内容,等价于在新镜像的​

​Dockerfile​

​后面添加了两条指令:

FROM image1

#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src      

在生成​

​java:8​

​​镜像的​

​Dockerfile​

​​中,ONBUILD指令可以用来指定设置Java环境变量的命令,之后以​

​java:8​

​​镜像为基础镜像的新镜像,就会自动设置Java环境变量,这样在由新镜像创建的容器中就可以直接使用​

​java -jar​

​这种命令。

STOPSIGNAL

格式

  • ​STOPSIGNAL signal​

    ​。

STOPSIGNAL指令用于设置停止信号,来指定容器的停止方式。容器默认的停止信号是SIGTERM,在容器停止的时候会给容器发送这个​

​signal​

​​,通过​

​--stop-signal​

​​选项可以设置自己需要的​

​signal​

​​,停止信号主要的目的是为了让容器内的应用程序在接收到​

​signal​

​​之后可以先做一些事情,实现容器的平滑退出,如果不做任何处理,容器将在一段时间之后强制退出,会造成业务的强制中断,这个时间默认是​

​10s​

​。