zoukankan      html  css  js  c++  java
  • 9、Dockerfile语法

      在Dockerfile中定义了很多关键字,通过关键字来完成Dockerfile的编写。
      Dockerfile官方文档

    9.1 FROM

      在Dockerfile中FROM主要是指定这个Dockerfile基于哪一个base image构建。Docker Dockerfile按顺序运行指令。一个Dockerfile 必须用FROM指令启动,放在第一行。

    FROM scratch        # 制作base image
    
    FROM centos         # 使用base image
    
    FROM ubuntu:14.04   # 使用指定版本的base image
    

    安全起见,尽量使用官方的image作为base image。

    9.2 LABEL

      在Dockerfile中LABEL实际上是英译了Metadata,就像是代码中的注释。主要包含了该镜像的作者、版本和描述信息。

    LABEL maintainer="staryjie@163.com"
    LABEL version="1.0"
    LABEL description="This is description"
    

    Metadata不可少!

    9.3 RUN

      在Dockerfile中RUN用来运行命令,其中命令必须是在第一行FROM中指定的base image所能运行的。每运行一次RUN,构建的image都会生成新的一层layer。

    RUN yum update && yum install -y vim 
        python-dev                # 反斜杠换行
    
    RUN apt-get update && apt-get install -y perl 
        pwgen --no-install-recommends && rm -rf 
        /var/lib/apt/lists/*      # 注意清理cache
    
    RUN /bin/bash -C 'source $HOME/.bashrc;echo $HOME'
    

    为了美观,复杂的RUN可以使用反斜杠换行。
    为了避免无用分层,多条命令尽量合并一行。

    9.4 WORKDIR

      在Dockerfile中WORKDIR用来设定当前工作目录,类似Linux系统中的cd命令。

    WORKDIR /root
    
    WORKDIR /test        # 如果没有该目录,则会自动创建
    WORKDIR demo
    RUN pwd              # 输出的结果应该是/test/demo
    

    用WORKDIR,不要使用RUN cd !!!
    为了避免出错,尽量使用绝对路径。

    9.4 ADD和COPY

      在Dockerfile中ADD和COPY作用相似,都是把本地的文件添加到docker image中。区别:ADD不仅可以添加文件,还可以解压缩文件,COPY不可以解压缩文件。

    ADD hello /
    
    ADD test.tar.gz /        # 添加到image的根目录并且解压
    
    WORKDIR /root
    ADD hello test/          # 将hello添加到image的/root/test/hello
    
    WORKDIR /root
    COPY hello test/         # 跟上面的效果一样
    

    大部分情况下COPY优于ADD。
    ADD除了COPY还有额外功能(解压)。
    添加远程文件/目录,请使用curl或者wget。

    9.5 ENV

      在Dockerfile中ENV来设置环境变量或者一些常量。可以在ENV设置的常量后面直接使用。

    ENV MYSQL_VERSION 5.6        # 设置常量
    RUN apt-get install -y mysql-server="${MYSQL_VERSION}" 
        && rm -rf /var/lib/apt/lists/*        #引用常量
    

    尽量使用ENV增加可维护性!

    9.6 VOLUME

      在Dockerfile中VOLUME用于向基于镜像创建的容器添加卷,一个卷可以存在于一个或多个容器的特定目录,这个目录可以绕过联合文件系统,并提供共享数据、数据持久化的功能。

    VOLUME ["/data"]
    

    9.7 EXPOSE

      在Dockerfile中EXPOSE设置容器暴露的端口,可以指定一个或多个端口。

    EXPOSE 80
    

    虽然在EXPOSE指令中已经暴露了指定的端口,但是在启动容器的时候还是要指定端口信息,容器本身不会自动暴露端口。

    9.8 CMD

      在Dockerfile中CMD设置容器启动后默认执行的命令和参数。如果定义了多个CMD,只会执行最后一个。

    CMD ["executable","param1","param2"]        # 执行形式,这是首选形式
    
    CMD ["param1","param2"]                     # 作为进入点的默认参数
    
    CMD command param1 param2                   # 壳形式
    

    不要定义多个CMD,多个CMD只有最后一个会执行。

    9.9 ENTRYPOINT

      在Dockerfile中ENTRYPOINT设置容器启动时运行的命令,可以让容器以应用程序或者服务器的形式运行,而且ENTRYPOINT设定的命令不会被忽略,一定会执行。

    COPY docker-entrypoint.sh /usr/local/bin/
    ENTRYPOINT ["docker-entrypoint.sh"]
    

    可以写一个shell脚本作为ENTRYPOINT的入口。

    RUN、CMD、ENTRYPOINT对比

    • RUN 执行命令并创建新的image layer
    • CMD 设置容器启动后默认执行的命令和参数
    • ENTRYPOINT 设置容器启动时运行的命令

    shell格式和exec格式

    • shell格式
    RUN apt-get install -y vim
    CMD echo "hello docker"
    ENTRYPOINT echo "hello docker"
    

      Dockerfile

    FROM centos
    ENV name Docker
    ENTRYPOINT echo "hello $name"
    

      构建镜像:

    docker build -t staryjie/centos-entrypoint-shell .
    

      运行容器:

    docker run staryjie/centos-entrypoint-shell
    
    hello Docker
    
    • exec格式
    RUN ["apt-get","install","-y","vim"]
    CMD ["/bin/echo","hello docker"]
    ENTRYPOINT ["/bin/echo","hello docker"]
    

      Dockerfile

    FROM centos
    ENV name Docker
    ENTRYPOINT ["/bin/echo","hello $name"]
    

      构建镜像:

    docker build -t staryjie/centos-entrypoint-exec .
    

      运行容器:

    docker run staryjie/centos-entrypoint-exec
    
    hello $name
    

      改写Dockerfile

    FROM centos
    ENV name Docker
    ENTRYPOINT ["/bin/bash","-c","echo hello $name"]
    

      构建镜像:

    docker build -t staryjie/centos-entrypoint-exec-new .
    

      运行容器:

    docker run staryjie/centos-entrypoint-exec-new
    
    hello Docker
    
    1. CMD
      • 容器启动时默认执行的命令
      • 如果docker run指定了其他命令,CMD命令会被忽略
      • 如果定义了多个CMD,只有最后一个会执行
    2. ENTRYPOINT
      • 让容器以应用程序或者服务的形式运行
      • 不会被忽略,一定会执行
  • 相关阅读:
    C++类继承内存布局(二)
    C++类继承内存布局(一)
    排序算法
    python 文件路径问题
    python map对象
    python reduce() 函数
    python eval 用法
    PyCharm引入自定义类报错
    Python中的lambda的简单介绍
    python time模块和datetime模块
  • 原文地址:https://www.cnblogs.com/jie-fang/p/10279690.html
Copyright © 2011-2022 走看看