docker教程-dockerfile语法

  • FROM关键字

        指定基础镜像,而且必须是第一条指令。若是不以任何镜像为基础,那么写法为:FROM scratch。同时意味着接下来所写的指令将做为镜像的第一层开始,语法:python

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest> 

        三种写法,其中<tag>和<digest> 是可选项,若是没有选择,那么默认值为latest,为了安全,尽可能使用官方image做为base imagemysql

 例:linux

FROM scratch #制做base image
FROM centos  #以centos做为base image
  • LABEL关键字

        为镜像指定标签,语法:sql

LABEL <key>=<value> <key>=<value> <key>=<value> ...

        一个Dockerfile种能够有多个LABEL,以下:docker

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."

     可是并不建议这样写,最好就写成一行,如太长须要换行的话则使用\符号shell

      以下:vim

LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"

    说明:LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖windows

例:centos

LABEL maintainer="asd@163.com"  #维护者信息
LABEL version="1.0"             #版本
LABEL description="这是描述"     #镜像描述信息
  • RUN关键字

    功能为运行指定的命令,每运行一次RUN对image而言都生成新的一层,RUN命令有两种格式安全

1. RUN <command>
2. RUN ["executable", "param1", "param2"]

    第一种后边直接跟shell命令

  • 在linux操做系统上默认 /bin/sh -c

  • 在windows操做系统上默认 cmd /S /C

    第二种是相似于函数调用。可将executable理解成为可执行文件,后面就是两个参数。

    两种写法比对:

  • RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME
  • RUN ["/bin/bash", "-c", "echo hello"]

    注意:多行命令不要写多个RUN,缘由是Dockerfile中每个指令都会创建一层.多少个RUN就构建了多少层镜像,会形成镜像的臃肿、多层,不只仅增长了构件部署的时间,还容易出错。

当命令较多,或较长时,建议将命令换行,RUN书写时的换行符是 \

例:

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/list/*
  • WORKDIR关键字

      设置工做目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。至关于 cd,若是不存在要打开的目录则会建立,能够设置屡次。语法:

WORKDIR /path/to/workdir

    例:

WORKDIR /ROOT  #将工做目录切换到root下
WORKDIR /test  #将工做目录切换到test目录  没有则建立
WORKDIR demo   #结合上一句 此时工做目录被切换到/test/demo目录下

  尽可能使用WORKDIR,而不使用RUN cd,尽可能使用局对目录。

  • ADD关键字

       一个复制命令,把文件复制到镜像中。若是把宿主机与容器想象成两台linux服务器的话,那么这个命令就相似于scp,只是scp须要加用户名和密码的权限验证,而ADD不用。语法以下:

1. ADD <src>... <dest>
2. ADD ["<src>",... "<dest>"]

<dest>路径的填写能够是容器内的绝对路径,也能够是相对于工做目录的相对路径

<src>能够是一个本地文件或者是一个本地压缩文件,还能够是一个url,若是把<src>写成一个url,那么ADD就相似于wget命令,ADD不只能够添加一个文件到指定目录,并且还能够将添加的压缩文件解压缩,

如如下写法都是能够的:

  • ADD test relativeDir/  #将test复制到容器内,相对于当前工做目录下的relativeDir目录中
  • ADD test /relativeDir #将test复制到容器内根目录下relativeDir目录中
  • ADD http://example.com/foobar / #将网络文件下载到根目录下

    尽可能不要把<scr>写成一个文件夹,若是<src>是一个文件夹了,将复制整个目录的内容,包括文件系统元数据

    有以下注意事项:

    一、若是源路径是个文件,且目标路径是以 / 结尾, 则docker会把目标路径看成一个目录,会把源文件拷贝到该目录下。若是目标路径不存在,则会自动建立目标路径。

    二、若是源路径是个文件,且目标路径是否是以 / 结尾,则docker会把目标路径看成一个文件。若是目标路径不存在,会以目标路径为名建立一个文件,内容同源文件;若是目标文件是个存在的文件,会用源文件覆盖它,固然只是内容覆盖,文件名仍是目标文件名。若是目标文件实际是个存在的目录,则会源文件拷贝到该目录下。 注意,这种状况下,最好显示的以 / 结尾,以免混淆。

    三、若是源路径是个目录,且目标路径不存在,则docker会自动以目标路径建立一个目录,把源路径目录下的文件拷贝进来。若是目标路径是个已经存在的目录,则docker会把源路径目录下的文件拷贝到该目录下。

    四、若是源文件是个归档文件(压缩文件),则docker会自动帮解压。

  • COPY关键字

    看这个名字就知道,又是一个复制命令,与ADD用法基本相同,COPY的<src>只能是本地文件,语法以下:

1. COPY <src>... <dest>
2. COPY ["<src>",... "<dest>"]

    例:

ADD hello /  #将hello文件复制到容器内根目录下
ADD test.tar.gz /   #将压缩文件添加到容器内根目录下并解压
WORKDIR /root  #将工做目录切换到root目录下
ADD hello test/   #将hello文件添加到/root/test目录下
WORKDIR /root  #将工做目录切换到root目录下
copy hello test/ #将hello文件复制到/root/test
  • ENV关键字

    功能为设置环境变量设置常量,语法有两种:   

1. ENV <key> <value>
2. ENV <key>=<value> ...

    二者的区别就是第一种是一次设置一个,第二种是一次设置多个。

例:

ENV MYSQL_VERSION 5.6 #设置常量
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" \   #使用常量
    && rm -rf /var/lib/apt/list/*
  • CMD关键字

    功能为容器启动时要运行的命令,语法有三种写法

1. CMD ["executable","param1","param2"]
2. CMD ["param1","param2"]
3. CMD command param1 param2

    第三种比较好理解了,就时shell这种执行方式和写法,第一种和第二种其实都是可执行文件加上参数的形式,举例说明两种写法:

  • CMD [ "sh", "-c", "echo $HOME" 
  • CMD [ "echo", "$HOME" ]

    补充细节:这里边包括参数的必定要用双引号,就是",不能是单引号。千万不能写成单引号,缘由是参数传递后,docker解析的是一个JSON array

    注意事项:

  •  容器启动时默认执行的命令
  • 若是docker run 指定了其余命令,CMD命令被忽略
  • 若是定义了多个CMD,只有最后一个会执行
  •     RUN & CMD

    不要把RUN和CMD搞混了。RUN是构件容器时就运行的命令以及提交运行结果,CMD是容器启动时执行的命令,在构件时并不运行,构件时牢牢指定了这个命令究竟是个什么样子

  • ENTRYPOINT关键字

        功能是启动时的默认命令,语法以下:

1. ENTRYPOINT ["executable", "param1", "param2"]
2. ENTRYPOINT command param1 param2

    与CMD比较说明(这俩命令太像了,并且还能够配合使用):

    1. 相同点:

  • 只能写一条,若是写了多条,那么只有最后一条生效

  • 容器启动时才运行,运行时机相同

    2. 不一样点:

  •  ENTRYPOINT不会被运行的command覆盖,而CMD则会被覆盖

  •  若是咱们在Dockerfile种同时写了ENTRYPOINT和CMD,而且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会做为ENTRYPOINT的参数

  • shell格式:即把要运行的命令当作shell执行

RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"

 

  • Exec格式:便是 命令,参数格式

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

    例:如下两个dockerfile结果相同

FROM centos  #指定基础镜像为centos
EVN name Docker   #设定常量name 值为Docker
ENTRYPOINT echo "hello $name"  #执行acho命令

 以上dockerfile生成的镜像运行容器时输出 hello Docker

FROM centos  #指定基础镜像为centos
EVN name Docker   #设定常量name 值为Docker
ENTRYPOINT ["/bin/echo", "hello $name"]  #执行acho命令

以上dockerfile生成的镜像运行容器时输出 hello $name,由于 ENTRYPOINT ["/bin/echo", "hello $name"] 指定容器启动时运行的就是echo命令  不会识别$为变量,作以下修改:

FROM centos  #指定基础镜像为centos
EVN name Docker   #设定常量name 值为Docker
ENTRYPOINT ["/bin/bash", "-c", "echo", "hello $name"]  #在shell中执行acho命令

容器启动时输出 hello Docker

相关文章
相关标签/搜索