美文网首页
Dockerfile(二)

Dockerfile(二)

作者: lconcise | 来源:发表于2019-10-26 17:58 被阅读0次

    学习Dockerfile

    FROM

    位于Dockerfile开头,表示基于什么镜像构建:

    FROM scratch # 制作base image
    FROM ubuntu:16.04 #使用ubuntu:16.04这个image

    出于安全考虑,最好使用官方的image作为base image。

    LABLE

    Dockerfile的元数据,描述作用。

    LABEL version="1.0" author="lconcise" description="dockerfile demo"

    Dockerfile最好都要有元数据,这样更易于理解。

    RUN

    运行命令,每次run都会生成一个图层,所以最好将命令合并:

    FROM ubuntu
    RUN apt-get update \
        && apt-get install -y vim
    

    \换行

    WORKDIR

    用于指定工作目录,切换路径:

    FROM ubuntu
    WORKDIR /test # 没有则自动创建test目录
    WORKDIR demo
    RUN pwd
    

    输出 /test/demo。
    最好不要用RUN cd来切换目录,而使用WORKDIR,这样可以减少不必要的图层,尽量使用绝对目录。

    ADD & COPY

    ADD 和COPY都可以将构建环境中的文件或目录复制到镜像中

    比如

    WORKDIR /demo
    ADD test test/
    
    WORKDIR /demo
    COPY test test/
    

    最终都会将test文件添加到/demo/test/目录下。
    区别:

    • ADD 添加的文件是压缩文件的话,会自动解压。

    • COPY 只能复制构建目录下的文件,ADD可以添加一个构建上下文中的文件或目录,也可以是一个URL,如:

      ADD http://wordpress.org/latest.zip /
      

    EVN

    设置环境变量常量。

    ENV MYSQL_VERSION 5.7
    RUN apt-get install -y mysql-server="${MYSQL_VERSION}"
    

    通过设定常量,可以提高可维护性。

    VOLUME & EXPOSE

    存储和网络,这里先略。

    CMD

    • 设置容器启动后默认执行的命令和参数。
    • docker run指定了其他命令,CMD命令会被忽略。
    • 定义了多个CMD,只有最后一个有效。

    比如有如下Dockerfile:

    FROM ubuntu
    ENV name lconcise
    CMD echo "hello docker"
    CMD echo "hello $name"
    

    构建镜像,运行:

      docker run [image]
    

    输出 hello lconcise。
    如果运行:

    docker run -it [image] /bin/bash
    

    则没有输出。

    ENTRYPOINT

    1. 设置容器启动时运行的命令。
    2. 不会被忽略,一定会执行。
    3. 一般写一个shell脚本作为ENTRYPOINT。

    比如mongodb官方Dockerfile末尾一段:

    COPY docker-entrypoint.sh /usr/local/bin/
    ENTRYPOINT ["docker-entrypoint.sh"]
    
    EXPOSE 27017
    CMD ["mongod"]
    

    ENTRYPOINT和CMD结合使用有一个技巧:
    比如有如下一个Dockerfile:

    FROM ubuntu
    ENTRYPOINT ["/bin/ls"]
    CMD []
    

    意思是在ubuntu这个镜像上构建,通过ENTRYPOINT运行/bin/ls命令,然后CMD []这行可以介绍额外的参数选项。
    通过这个Dockerfile构建镜像后(image id为95c35bb00761),分别运行下面这些命令来创建容器:


    image.png

    可以看到我们通过相同的镜像构建出了不同的容器。

    Shell 和 Exec 格式

    在Dockerfile中,命令的写法有Shell格式和Exec格式:

    Shell格式的Dockerfile如下:

    RUN apt-get install -y vim
    CMD echo "hello world"
    ENTRYPOINTT echo "hello world"
    

    Exec格式如下所示:

    RUN ["apt-get","install","-y","vim"]
    CMD ["/bin/echo","hello world"]
    ENTRYPOINTT ["/bin/echo","hello world"]
    

    在使用Exec格式的时候需要注意和常量的搭配使用问题,比如在Shell格式下:

    FROM ubuntu
    ENV name lconcise
    ENTRYPOINTER echo "hello $name"
    

    创建镜像,运行容器后输出:hello lconcise。
    但是在Exec格式下:

    FROM ubuntu
    ENV name lconcise
    ENTRYPOINTER ["/bin/echo","hello $name"]
    

    创建镜像,运行容器后输出:hello $name。
    正确的写法是:

    FROM ubuntu
    ENV name mrbird
    ENTRYPOINTER ["/bin/bash","-c","echo hello $name"]
    

    参考文档:
    https://blog.fundebug.com/2017/05/15/write-excellent-dockerfile/
    https://docs.docker.com/engine/reference/builder/
    https://mrbird.cc/Dockerfile.html

    相关文章

      网友评论

          本文标题:Dockerfile(二)

          本文链接:https://www.haomeiwen.com/subject/jnurvctx.html