zoukankan      html  css  js  c++  java
  • 05Dockerfile简介

             Dockerfile是一个用于构建Docker镜像的文本文件,其中包含了创建Docker镜像的全部指令。基于这些指令,可以使用”docker  build”命令来创建镜像。

     

    一:用法

             ”docker  build”命令通过Dockerfile,以及一个上下文环境来构建镜像。所谓构建上下文,是指本地目录中的所有文件。比如使用当前目录作为上下文来构建镜像:

    $ docker build .

     

             构建流程中,第一件事就是将上下文中的所有文件上传给Docker deamon。因此,一般情况下,上下文的目录中应该只包含Dockerfile,以及其他必要的文件。

             一般情况下,Dockerfile的文件名就是”Dockerfile”,并位于上下文的根目录下。不过可以通过”-f”选项指定其他其他文件作为Dockerfile,比如:

    $ docker build -f /path/to/a/Dockerfile .

     

             可以通过”-t”选项,指明要创建的镜像名以及tag,比如:

    $ docker build -t shykes/myapp:1.0.2 .

     

             Docker daemon逐条执行Dockerfile中的指令,并将指令执行结果提交为中间镜像。注意,每条指令都是独立运行,因此向”RUN  cd /tmp”这样的指令,对于后续的指令没有任何效果。

     

             为了加快”docker  build”的执行速度,Docker会尽可能的重用中间镜像,也就是所谓的缓存。

             Docker在执行每条指令时,都会检查缓存中是否有可重用的镜像,若有则直接使用该镜像,而无需创建新的重复镜像。检查镜像是否可重用的基本规则如下:

             1:若父镜像已经处于缓存中,则会将下一条指令与该父镜像的所有子镜像进行对比,查看这些子镜像是否是使用相同指令构建的,若是,则可以使用该子镜像。

             2:一般情况下,仅将Dockerfile中的指令与子镜像进行比对就足够了。不过还有其他一些指令需要额外的检查。

             比如像ADD和COPY指令,除了对比指令之外,还会检查镜像中的文件内容。对于这两条指令,会检查相应文件的内容,计算其校验码,并与镜像中相应文件的校验码进行匹配。因此,如果文件内容发生了变化,则该子镜像也不再可用。

             3:一旦缓存镜像不可用,则Dockerfile中的后续指令将被执行,并产生新的中间镜像。

             下面就是一个利用缓存构建镜像的输出:

    $ docker build -t svendowideit/ambassador .
    Sending build context to Docker daemon 15.36 kB
    Step 0 : FROM alpine:3.2
     ---> 31f630c65071
    Step 1 : MAINTAINER SvenDowideit@home.org.au
     ---> Using cache
     ---> 2a1c91448f5f
    Step 2 : RUN apk update &&      apk add socat &&        rm -r /var/cache/
     ---> Using cache
     ---> 21ed6e7fbb73
    Step 3 : CMD env | grep _TCP= | (sed 's/.*_PORT_([0-9]*)_TCP=tcp://(.*):(.*)/socat -t 100000000 TCP4-LISTEN:1,fork,reuseaddr TCP4:2:3 &/' && echo wait) | sh
     ---> Using cache
     ---> 7ea8aef582cc
    Successfully built 7ea8aef582cc
    

     

    二:格式:

             Dockerfile的格式如下:

    # Comment
    INSTRUCTION arguments
    

             指令不区分大小写。但是,一般约定为全部大写,以便与其参数区分开。

             以”#”作为开头的行,将被视为注释行。如果”#”出现在行中间,则将会被视为参数。

     

    三:常用指令:

    1:FROM

             Dockerfile中,第一条指令必须是”FROM”,以便指定基础镜像。所谓基础镜像,就是没有父镜像的镜像。 FROM指定镜像基于哪个基础镜像创建。比如

    FROM ubuntu

             这表示新的镜像将基于Ubuntu的镜像来构建。

     

    2:MAINTAINER

             一般情况下,FROM指令的下一条指令就是” MAINTAINER”指令。用于指定新镜像的作者:

    MAINTAINER <name>

     

    3:RUN

             在shell或者exec的环境下执行的命令。有两种格式:

    RUN <command>       (shell form, the command is run in a shell - /bin/sh -c)
    RUN ["executable", "param1", "param2"] (exec form)
    

             RUN指令会在新创建的镜像上添加新的层面,接下来提交的结果用在Dockerfile的下一条指令中。

     

    4: ADD

             复制文件指令。它有两个参数<source>和<destination>。<destination>是容器内的路径,而<source>可以是一个URL,或者是上下文中的一个文件。ADD指令将<source>所表示的文件或者目录添加到容器的<destination>中。

             注意:

             a:如果<src>是本地文件,则该文件必须位于上下文中。

             b:如果<src>是目录,在目录中的所有内容都会复制到容器中。

             c:如果<src>是本地的一个tar压缩文件,则复制时会将其解压。

             d:如果<dest>不存在,则会在容器中创建,包括其中包含的目录。

     

    5:CMD

             提供了容器默认的执行命令。有三种格式,推荐exec格式:

    CMD ["executable","param1","param2"] (exec form, this is the preferred form)
    CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
    CMD command param1 param2 (shell form)
    

             Dockerfile只允许使用一次CMD指令。如果有多个CMD指令,则只有最后一个指令生效。

     

             CMD指令主要用于提供运行容器时,该容器默认需要执行的命令。

             如果使用的是CMD的shell形式,则CMD后的命令将以”/bin/sh -c”执行。若不希望在shell中执行,则CMD需要使用exec的形式,这也是更被提倡的做法。

             如果用户在执行”docker  run”时提供了容器要运行的命令,则该命令会覆盖CMD的内容。

     

    6:ENTRYPOINT

             提供了容器默认的执行命令。有两种格式,推荐exec格式:

    ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)
    ENTRYPOINT command param1 param2 (shell form)
    

             在使用”dockerrun”命令运行容器时,指定的命令参数都会追加到exec形式的ENTRYPOINT中,并且会覆盖掉CMD中的内容。比如"docker run <image>-d",就会将”-d”追加到exec形式的ENTRYPOINT中。

             shell形式的ENTRYPOINT会覆盖掉CMD或者”dockerrun”中的命令。但是这种形式的命令是在”/bin/sh -c”下执行的。

             只有最后一个ENTRYPOINT会起作用。

     

             可以在ENTRYPOINT中指定容器要执行的命令和参数,并在CMD中指定该命令的其他参数,比如:

    FROM ubuntu
    ENTRYPOINT ["top", "-b"]
    CMD ["-c"]
    

     

             虽然CMD和ENTRYPOINT都用来指定容器运行时的指令。但是它们又有不同的意义:

             a:Dockerfile中应该至少指定一个CMD或者ENTRYPOINT;

             b:CMD中可用于指定ENTRYPOINT中命令的参数;如果使用”docker run”指定了容器运行指令,则它会覆盖掉CMD中的内容。

             下表描述了ENTRYPOINT和CMD相互作用的结果:

     

    7:EXPOSE

             指定容器在运行时监听的端口。语法如下:

    EXPOSE <port> [<port>...]

             注意,EXPOSE指令并不指定容器与主机间的端口映射。要想指定端口映射,必须在docker run时使用-p或-P参数。

     

    8:ENV

             设置环境变量。有两种格式:

    ENV <key> <value>
    ENV <key>=<value> ...
    

             该指令将环境变量<key>设置为<value>。该环境变量在Dockerfile后续的指令中保持有效。该环境变量在容器运行时也保持有效。

     

    四:注意

             1:Dockerfile中,通过ENTRYPOINT和CMD指定的容器默认运行程序,比如apache、redis等,如果以后台的方式运行,则该容器启动后会立即结束,因为容器运行时,必须要有一个前台程序。

             2:容器中应该只运行一个进程;

     

    五:例子

             下面是一个制作redis镜像的Dockerfile:

    FROM oraclelinux:6.6
    MAINTAINER hehe
    
    RUN yum update –y && yum -y install redis
    
    ADD redis.conf /etc/redis.conf
    
    EXPOSE 6379
    
    CMD ["redis-server", "/etc/redis.conf"]
    

             该Dockerfile很简单:

             FROM指明该镜像以oraclelinux:6.6为基础镜像;

             MAINTAINER指明镜像作者是hehe;

             然后就是运行”yum –y install redis”命令安装redis;

             接下来,使用ADD指令,将上下文中的redis.conf文件复制到容器中的/etc/目录下;

             然后使用EXPOSE指明该镜像监听6379端口;

             最后,使用CMD指明容器运行时的指令是”redis-server  /etc/redis.conf”

     

             写好Dockerfile之后,使用下面的命令构建镜像:

    docker build -t redis .

  • 相关阅读:
    九度OJ 1010 A+B
    九度OJ 1052 找x
    oracle数据库创建备份与恢复 脚本
    在select标签中添加a标签
    如何在select标签中使用a标签跳转页面
    网站访问不了
    js实现input的赋值
    PHP如何实现百万级数据导出
    互联网产品需求管理杂思2需求收集,互联网营销 狼人:
    做网站用UTF8还是GB2312?,互联网营销 狼人:
  • 原文地址:https://www.cnblogs.com/gqtcgq/p/7247037.html
Copyright © 2011-2022 走看看