zoukankan      html  css  js  c++  java
  • Dockerfile 文件说明

    原文 https://blog.csdn.net/cojn52/article/details/104371306

    1、Dockerfile 常用指令
    下面列出了 Dockerfile 中最常用的指令,完整列表和说明可参看官方文档。
    FROM

    指定 base 镜像。
    支持三种格式:
    FROM
    FROM :
    FROM @

    FROM指令必须指定,且需要在Dockerfile其他指令的前面。指定的基础指令可以是官方远程仓库中的,也可以是位于本地仓库。后续的指令都依赖于该指令指定的image。 在同一个Dockerfile中建立多个镜像时,可以使用多个FROM指令。

    MAINTAINER
    设置镜像的作者,可以是任意字符串。

    格式:
    MAINTAINER
    示例:
    MAINTAINER Jasper Xu​​​​​​​

    COPY
    格式为:
    COPY ...
    COPY ["", ...""], shell中执行

    复制本地的src到容器的dest, 和ADD指令相似,但是COPY不支持URL和压缩包。
    将文件从 build context 复制到镜像。
    COPY 支持两种形式:
    COPY src dest
    COPY ["src", "dest"]
    注意:src 只能指定 build context 中的文件或目录。
    ADD
    与 COPY 类似,从 build context 复制文件到镜像。不同的是,如果 src 是归档文件(tar, zip, tgz, xz 等),文件会被自动解压到 dest。
    格式:ADD ...
    ADD ["", ...""]

    从src目录复制文件到容器的dest目录,src可以是Dockerfile所在目录的相对路径,也可以是一个url,还可以是一个压缩包
    注意事项:

    1. src必须在构建的上下⽂内,不能使⽤例如: ADD ../some/something ,因为 docker build 命令⾸先会将上下⽂路径和其⼦⽬录发送到docker daemon
    2. 如果src是⼀个URL,同时dest不以斜杠结尾,dest将会被视为⽂件,src对应内容⽂件将会被下载到dest
    3. 如果src是⼀个URL,同时dest以斜杠结尾,dest将被视为⽬录,src对应内容将会被下载到dest⽬录
    4. 如果src是⼀个⽬录,那么整个⽬录其下的内容将会被拷⻉,包括⽂件系统元数据
    5. 如果⽂件是可识别的压缩包格式,则docker会⾃动解压

    ENV设置环境变量,环境变量可被后面的指令使用
    格式:ENV
    ENV =

    指定环境变量,会被后续的RUN指令使用,并在容器使用后可以通过docker inspect查看这个环境变量,也可以通过使用docker run --env =来修改环境变量
    例如:
    ...
    ENV MY_VERSION 1.3
    RUN apt-get install -y mypackage=$MY_VERSION
    ...
    EXPOSE

    指定容器中的进程会监听某个端口,Docker 可以将该端口暴露出来。
    格式:
    EXPOSE [...] 为Docker容器设置对外的端口号,使用时可以-p选项或者-P选项。

    映射⼀个端⼝的例子:
    EXPOSE port1
    相应的运⾏容器使⽤的命令docker run -p port1 image
    也可以使⽤-P选项启动docker run -P image
    映射多个端⼝示例EXPOSE port1 port2 port3
    相应的运⾏容器使⽤的命令docker run -p port1 -p port2 -p port3 image
    还可以指定需要映射到宿主机器上的某个端⼝号docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image
    注意:
    #EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
    #默认是TCP

    VOLUME

    将文件或目录声明为 volume。
    格式为: VOLUME ["/data"]

    格式:
    VOLUME ["/path/to/dir"]
    示例:
    VOLUME ["/data"]
    VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
    注:
      一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
    卷可以容器间共享和重用
    容器并不一定要和其它容器共享卷
    修改卷后会立即生效
    对卷的修改不会对镜像产生影响
    卷会一直存在,直到没有任何容器在使用它

    [root@localhost imgl]# vi Dockerfile

    Description: test image

    FROM busybox:latest
    LABEL maintainer "NAME docker@keji.com"
    COPY yum.repos.d /etc/yum.repos.d/

    ADD http://nginx.org/download/nginx-1.17.3.tar.gz /usr/local/src/

    ADD nginx-1.17.3.tar.gz /usr/local/src/
    VOLUME /data/mysql

    注意:

    容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失,所以当数据需要持久化时用这个命令。
    一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统
    卷可以容器间共享和重用 可以关注参数 --volumes-from
    容器并不一定要和其它容器共享卷
    修改卷后会立即生效
    对卷的修改不会对镜像产生影响卷会一直存在,直到没有任何容器在使用它
    使容器中的⼀个⽬录具有持久化存储数据的功能,该⽬录可以被容器本身使⽤,也可以共享给其他容器

    WORKDIR
    为后面的 RUN, CMD, ENTRYPOINT, ADD 或 COPY 指令设置镜像中的当前工作目录。

    格式为: WORKDIR /path/to/workdir

    切换⽬录指令,类似于cd命令,对RUN、CMD、ENTRYPOINT⽣效。
    注意:
    通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。

    RUN
    在容器中运行指定的命令。

    支持两种格式:

    RUN 在shell终端中运行命令,在Linux中默认是/bin/sh -c

    RUN["executable", "param1", "param2"],使用exec执行,指定其他终端,例如:RUN["/bin/bash", "-c", "echo hello"],该方式会被转成json数组。

    RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:
    shell执行
    格式:
    RUN
    exec执行
    格式:
    RUN ["executable", "param1", "param2"]
    示例:
    RUN ["executable", "param1", "param2"]
    RUN apk update
    RUN ["/etc/execfile", "arg1", "arg1"]
    注:
      RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
      基于基础镜像执行,在操作时评估好基础镜像的能力
      注意:json数组中,要使用双引号

    CMD

    容器启动时运行指定的命令。
    Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。CMD 可以被 docker run 之后的参数替换。
    CMD ["executable", "param1", "param2"], 推荐使用该方式
    CMD ["param1", "param2"],为ENTRYPOINT指令提供预设参数
    CMD command param1 param2 在SHELL中执行

    CMD指令的主要目的是为执行容器提供默认值,每个Dockerfile只有一个CMD命令,如果指定了多个CMD命令,也只会有一条执行,如果启动容器的时候指定了运行的命令,则会覆盖掉CMD指定的命令。

    格式:
    CMD ["executable","param1","param2"] (执行可执行文件,优先)
    CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
    CMD command param1 param2 (执行shell内部命令)
    示例:
    CMD echo "This is a test." | wc -
    CMD ["/usr/bin/wc","--help"]
    注:
      CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
    ENTRYPOINT
    设置容器启动时运行的命令。

    格式为: ENTRYPOINT ["executable", "param1", "param2"]

               ENTRYPOINT command param1 param2
    

    指定Docker容器启动时执⾏的命令,Dockerfile 中可以有多个 ENTRYPOINT 指令,但只有最后一个生效。
    CMD 或 docker run 之后的参数会被当做参数传递给 ENTRYPOINT

    LABEL

    格式为:LABEL = = = 为镜像添加元数据。

    注意:

    使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。
    LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖
    USER

    格式为: USER ⽤户名

    设置启动容器的⽤户,默认是root⽤户

    注:

    使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。
    ARG

    格式为: ARG [=]

    ARG指令定义⼀个变量。

    注意:

    如果用户在build镜像时指定了一个参数没有定义在Dockerfile中,那么将有一个Warning:[Warning] One or more build-args [foo] were not consumed
    ARG定义的参数默认值,当build镜像时没有指定参数值,将会使用这个默认值

    ONBUILD

    格式为:ONBUILD [INSTRUCTION]

    指定当前建⽴的镜像作为其他镜像的基础时,所执⾏的命令。
    注意:
    当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发只对当前镜像的子镜像生效。
    比如当前镜像为A,在Dockerfile种添加:ONBUILD RUN ls -al 这个 ls -al 命令不会在A镜像构建或启动的时候执行,此时有一个镜像B是基于A镜像构建的,那么这个ls -al 命令会在B镜像构建的时候被执行。

    STOPSIGNAL
    该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。此信号可以是与内核的系统调用表中的位置匹配的有效无符号数,例如9,或SIGNAME格式的信号名,例如SIGKILL

    HEALTHCHECK
    HEALTHCHECK指令告诉Docker如何测试容器以检查它是否仍在工作。即使服务器进程仍在运行,这也可以检测到陷入无限循环且无法处理新连接的Web服务器等情况。
    当容器指定了运行状况检查时,除了正常状态外,它还具有运行状况。这个状态最初是starting。每当健康检查通过时,它就会变成healthy(以前的状态)。经过一定数量的连续失败后,它就变成了unhealthy

    HEALTHCHECKDockerfile中只能有一条指令。如果列出多个,则只有最后一个HEALTHCHECK生效
    SHELL
    SHELL指令允许覆盖用于shell形式的命令的默认shell 。Linux上的默认shell是["/bin/sh", “-c”],而在Windows上[“cmd”, “/S”, “/C”]。

    SHELL指令必须以JSON格式写入Dockerfile
    SHELL指令可以多次出现。每条SHELL指令都会覆盖所有先前的SHELL指令,并影响所有后续指令

    2、RUN、CMD 和 ENTRYPOINT的区别
    区别:

    RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。
    CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换。
    ENTRYPOINT 配置容器启动时运行的命令。
    Shell 和 Exec 格式
    我们可用两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令:Shell 格式和 Exec 格式,二者在使用上有细微的区别。

    Shell 格式

    例如:

    RUN apt-get install python3
    CMD echo "Hello world"
    ENTRYPOINT echo "Hello world"
    当指令执行时,shell 格式底层会调用 /bin/sh -c
    例如下面的 Dockerfile 片段:

    ENV name Cloud Man
    ENTRYPOINT echo "Hello, $name"
    执行 docker run 将输出:
    Hello, Man
    注意环境变量 name 已经被值 Cloud Man 替换。
    下面来看 Exec 格式。

    Exec 格式
    ["executable", "param1", "param2", ...]
    例如:

    RUN ["apt-get", "install", "python3"]
    CMD ["/bin/echo", "Hello world"]
    ENTRYPOINT ["/bin/echo", "Hello world"]
    当指令执行时,会直接调用 ,不会被 shell 解析。
    例如下面的 Dockerfile 片段:

    ENV name Man
    ENTRYPOINT ["/bin/echo", "Hello, $name"]
    运行容器将输出:
    Hello, $name
    注意环境变量“name”没有被替换。
    如果希望使用环境变量,照如下修改

    ENV name Man
    ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]
    运行容器将输出:
    Hello, Man
    CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 则两种格式都可以。
    RUN
    RUN 指令通常用于安装应用和软件包。
    RUN 在当前镜像的顶部执行命令,并通过创建新的镜像层。Dockerfile 中常常包含多个 RUN 指令。
    RUN 有两种格式:
    Shell 格式:RUN
    Exec 格式:RUN ["executable", "param1", "param2"]
    下面是使用 RUN 安装多个包的例子:

    RUN apt-get update && apt-get install -y
    bzr
    cvs
    git
    mercurial
    subversion

    注意:apt-get update 和 apt-get install 被放在一个 RUN 指令中执行,这样能够保证每次安装的是最新的包。如果 apt-get install 在单独的 RUN 中执行,则会使用 apt-get update 创建的镜像层,而这一层可能是很久以前缓存的。
    CMD
    CMD 指令允许用户指定容器的默认执行的命令。
    此命令会在容器启动且 docker run 没有指定其他命令时运行。
    如果 docker run 指定了其他命令,CMD 指定的默认命令将被忽略。
    如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效。
    CMD 有三种格式:
    Exec 格式:CMD ["executable","param1","param2"]
    这是 CMD 的推荐格式。
    CMD ["param1","param2"] 为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT 必须使用 Exec 格式。
    Shell 格式:CMD command param1 param2
    Exec 和 Shell 格式前面已经介绍过了。
    第二种格式 CMD ["param1","param2"] 要与 Exec 格式 的 ENTRYPOINT 指令配合使用,其用途是为 ENTRYPOINT 设置默认的参数。我们将在后面讨论 ENTRYPOINT 时举例说明。
    下面看看 CMD 是如何工作的。Dockerfile 片段如下:
    CMD echo "Hello world"
    运行容器 docker run -it [image] 将输出:
    Hello world
    但当后面加上一个命令,比如 docker run -it [image] /bin/bash,CMD 会被忽略掉,命令 bash 将被执行:
    root@10a32dc7d3d3:/#
    ENTRYPOINT
    ENTRYPOINT 指令可让容器以应用程序或者服务的形式运行。
    ENTRYPOINT 看上去与 CMD 很像,它们都可以指定要执行的命令及其参数。不同的地方在于 ENTRYPOINT 不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。
    ENTRYPOINT 有两种格式:
    Exec 格式:ENTRYPOINT ["executable", "param1", "param2"] 这是 ENTRYPOINT 的推荐格式。
    Shell 格式:ENTRYPOINT command param1 param2
    在为 ENTRYPOINT 选择格式时必须小心,因为这两种格式的效果差别很大。
    Exec 格式
    ENTRYPOINT 的 Exec 格式用于设置要执行的命令及其参数,同时可通过 CMD 提供额外的参数。
    ENTRYPOINT 中的参数始终会被使用,而 CMD 的额外参数可以在容器启动时动态替换掉。
    比如下面的 Dockerfile 片段:
    ENTRYPOINT ["/bin/echo", "Hello"]
    CMD ["world"]
    当容器通过 docker run -it [image] 启动时,输出为:
    Hello world
    而如果通过 docker run -it [image] Man 启动,则输出为:
    Hello Man
    Shell 格式
    ENTRYPOINT 的 Shell 格式会忽略任何 CMD 或 docker run 提供的参数。
    最佳实践
    使用 RUN 指令安装应用和软件包,构建镜像。
    如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。
    如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。

  • 相关阅读:
    div居中方法总结
    windows下配置nginx环境
    webpack+babel+react操作小结
    JavaScript数组常用操作总结
    MyBatis使用Generator自动生成代码
    如何上Chrome谷歌商店
    深入理解Spring IOC
    SpringMVC概要总结
    mybatis防止sql注入
    Redis和Memcache的区别分析
  • 原文地址:https://www.cnblogs.com/wang2650/p/14261455.html
Copyright © 2011-2022 走看看