Dockerfile

Dockerfile指令详解

Dockerfile_第1张图片
Dockerfile指令详解

一.指令:FROM   功能:设置基础镜像(指定base镜像 linux发行版本)

语法:FROM < image>[:< tag> | @< digest>] 

注意:如果忽略tag选项,会使用latest镜像

实例:FORM ubuntu:14.04

二.指令:MAINTAINER   功能:设置镜像的作者

语法:MAINTAINER

三.指令:RUN 

语法:RUN < command> 

           RUN [“executable”,”param1”,”param2”] 

提示:RUN指令会生成容器,在容器中执行脚本,容器使用当前镜像,Docker Daemon会将该容器提交为一个中间镜像,供后面的指令使用

补充:RUN指令第一种方式为shell方式,可以在其中使用\将脚本分为多行 

          RUN指令第二种方式为exec方式,

实例:RUN source $HOME/.bashrc;\ 

          echo $HOME

          RUN [“/bin/bash”,”-c”,”echo hello”]

四.指令:CMD

功能:设置容器的启动命令(容器启动时运行 [ ]指定的命令)

语法:CMD [“executable”,”param1”,”param2”] 

           CMD [“param1”,”param2”] 

           CMD < command> 

提示:CMD第一种、第三种方式和RUN类似,第二种方式为ENTRYPOINT参数方式,为entrypoint提供参数列表 

注意:Dockerfile中只能有一条CMD命令,如果写了多条则最后一条生效

实例:CMD ["/bin/echo", "this is a echo test"]

首先创建Dockerfile文件 :touch Dockerfile  (默认当docker build执行时使用Dockerfile)

然后编辑Dockerfile文件:

Dockerfile
Dockerfile_第2张图片
创建test镜像


五.指令:LABEL      功能:设置镜像的标签

延伸:镜像标签可以通过docker inspect查看 

格式:LABEL < key>=< value> < key>=< value> … 

提示:不同标签之间通过空格隔开 

注意:每条指令都会生成一个镜像层,Docker中镜像最多只能有127层,如果超出Docker Daemon就会报错,如LABEL ..=.. <假装这里有个换行> LABEL ..=..合在一起用空格分隔就可以减少镜像层数量,同样,可以使用连接符\将脚本分为多行 

镜像会继承基础镜像中的标签,如果存在同名标签则会覆盖

六.指令:EXPOSE  功能:设置镜像暴露端口,记录容器启动时监听那些端口

语法:EXPOSE < port> < port> …

延伸:镜像暴露端口可以通过docker inspect查看 

提示:容器启动时,Docker Daemon会扫描镜像中暴露的端口,如果加入-P参数,Docker Daemon会把镜像中所有暴露端口导出,并为每个暴露端口分配一个随机的主机端口(暴露端口是容器监听端口,主机端口为外部访问容器的端口) 

注意:EXPOSE只设置暴露端口并不导出端口,只有启动容器时使用-P/-p才导出端口,这个时候才能通过外部访问容器提供的服务

七.指令:ENV    功能:设置镜像中的环境变量

语法:ENV < key>=< value>…|< key> < value> 

注意:环境变量在整个编译周期都有效,第一种方式可设置多个环境变量,第二种方式只设置一个环境变量 

提示:通过${变量名}或者 $变量名使用变量,使用方式${变量名}时可以用${变量名:-default} ${变量名:+cover}设定默认值或者覆盖值 

ENV设置的变量值在整个编译过程中总是保持不变的

实例:ENV abc=hello  

           ENVabc=bye def=$abc  

           ENVghi=$abc  

八.指令:ADD    功能:复制文件到镜像中    

语法:ADD < src>… < dest>|[“< src>”,… “< dest>”] 

注意:当路径中有空格时,需要使用第二种方式 

当src为文件或目录时,Docker Daemon会从编译目录寻找这些文件或目录,而dest为镜像中的绝对路径或者相对于WORKDIR的路径 

提示:src为目录时,复制目录中所有内容,包括文件系统的元数据,但不包括目录本身 

src为压缩文件,并且压缩方式为gzip,bzip2或xz时,指令会将其解压为目录 

如果src为文件,则复制文件和元数据 

如果dest不存在,指令会自动创建dest和缺失的上级目录

实例:

#test

FROM ubuntu

MAINTAINER hello

ADD test1.txt test1.txt

ADD test1.txt test1.txt.bak

ADD test1.txt /mydir/ADD data1  data1

ADD data2  data2

ADD zip.tar/myzip

注意事项:

1、如果源路径是个文件,且目标路径是以 / 结尾, 则docker会把目标路径当作一个目录,会把源文件拷贝到该目录下。

如果目标路径不存在,则会自动创建目标路径。

2、如果源路径是个文件,且目标路径是不是以 / 结尾,则docker会把目标路径当作一个文件。

如果目标路径不存在,会以目标路径为名创建一个文件,内容同源文件;

如果目标文件是个存在的文件,会用源文件覆盖它,当然只是内容覆盖,文件名还是目标文件名。

如果目标文件实际是个存在的目录,则会源文件拷贝到该目录下。 注意,这种情况下,最好显示的以 / 结尾,以避免混淆。

3、如果源路径是个目录,且目标路径不存在,则docker会自动以目标路径创建一个目录,把源路径目录下的文件拷贝进来。

如果目标路径是个已经存在的目录,则docker会把源路径目录下的文件拷贝到该目录下。

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

九.指令:COPY

功能描述:复制文件到镜像中 

语法:COPY < src>… < dest>|[“< src>”,… “< dest>”] 

提示:指令逻辑和ADD十分相似,同样Docker Daemon会从编译目录寻找文件或目录,dest为镜像中的绝对路径或者相对于WORKDIR的路径

与ADD的区别:COPY指令和ADD指令功能和使用方式类似。只是COPY指令不会做自动解压工作。

十.指令:ENTRYPOINT 

功能描述:设置容器的入口程序 

语法:ENTRYPOINT [“executable”,”param1”,”param2”] 

ENTRYPOINT command param1 param2(shell方式) 

提示:入口程序是容器启动时执行的程序,docker run中最后的命令将作为参数传递给入口程序 

          入口程序有两种格式:exec、shell,其中shell使用/bin/sh -c运行入口程序,此时入口程序不能接收信号量 

当Dockerfile有多条ENTRYPOINT时只有最后的ENTRYPOINT指令生效 

如果使用脚本作为入口程序,需要保证脚本的最后一个程序能够接收信号量,可以在脚本最后使用exec或gosu启动传入脚本的命令 

注意:通过shell方式启动入口程序时,会忽略CMD指令和docker run中的参数 

为了保证容器能够接受docker stop发送的信号量,需要通过exec启动程序;如果没有加入exec命令,则在启动容器时容器会出现两个进程,并且使用docker stop命令容器无法正常退出(无法接受SIGTERM信号),超时后docker stop发送SIGKILL,强制停止容器 

例子:FROM ubuntu <换行> ENTRYPOINT exec top -b

十一.指令:VOLUME 

功能描述:设置容器的挂载点 

语法:VOLUME [“/data”] 

VOLUME /data1 /data2 

提示:启动容器时,Docker Daemon会新建挂载点,并用镜像中的数据初始化挂载点,可以将主机目录或数据卷容器挂载到这些挂载点

十二.指令:WORKDIR 

功能描述:设置RUN CMD ENTRYPOINT ADD COPY指令的工作目录 

语法:WORKDIR < Path> 

提示:如果工作目录不存在,则Docker Daemon会自动创建 

Dockerfile中多个地方都可以调用WORKDIR,如果后面跟的是相对位置,则会跟在上条WORKDIR指定路径后(如WORKDIR /A   WORKDIR B   WORKDIR C,最终路径为/A/B/C)

十三.指令:USER 

功能描述:设置RUN CMD ENTRYPOINT的用户名或UID 

语法:USER < name>

十四.指令:ARG 

功能描述:设置编译变量 

语法:ARG < name>[=< defaultValue>] 

注意:ARG从定义它的地方开始生效而不是调用的地方,在ARG之前调用编译变量总为空,在编译镜像时,可以通过docker build –build-arg < var>=< value>设置变量,如果var没有通过ARG定义则Daemon会报错 

可以使用ENV或ARG设置RUN使用的变量,如果同名则ENV定义的值会覆盖ARG定义的值,与ENV不同,ARG的变量值在编译过程中是可变的,会对比使用编译缓存造成影响(ARG值不同则编译过程也不同) 

例子:ARG CONT_IMAG_VER <换行> RUN echo $CONT_IMG_VER 

ARG CONT_IMAG_VER <换行> RUN echo hello 

当编译时给ARG变量赋值hello,则两个Dockerfile可以使用相同的中间镜像,如果不为hello,则不能使用同一个中间镜像

十五.指令:ONBUILD 

功能描述:设置自径想的编译钩子指令 

语法:ONBUILD [INSTRUCTION] 

提示:从该镜像生成子镜像,在子镜像的编译过程中,首先会执行父镜像中的ONBUILD指令,所有编译指令都可以成为钩子指令

十六.指令:STOPSIGNAL 

功能描述:设置容器退出时,Docker Daemon向容器发送的信号量 

语法:STOPSIGNAL signal 

提示:信号量可以是数字或者信号量的名字,如9或者SIGKILL,信号量的数字说明在Linux系统管理中有简单介绍


补充:ONBUILD流程

编译时,读取所有ONBUILD镜像并记录下来,在当前编译过程中不执行指令

生成镜像时将所有ONBUILD指令记录在镜像的配置文件OnBuild关键字中

子镜像在执行FROM指令时会读取基础镜像中的ONBUILD指令并顺序执行,如果执行过程中失败则编译中断;当所有ONBUILD执行成功后开始执行子镜像中的指令

子镜像不会继承基础镜像中的ONBUILD指令

补充:CMD ENTRYPOINT和RUN的区别

RUN指令是设置编译镜像时执行的脚本和程序,镜像编译完成后,RUN指令的生命周期结束

容器启动时,可以通过CMD和ENTRYPOINT设置启动项,其中CMD叫做容器默认启动命令,如果在docker run命令末尾添加command,则会替换镜像中CMD设置的启动程序;ENRTYPOINT叫做入口程序,不能被docker run命令末尾的command替换,而是将command当作字符串,传递给ENTRYPOINT作为参数

FROMubuntu

ENTRYPOINT ["ps"]

//通过命令docker run --rm test启动容器,打印ps的输出//通过命令docker run --rm test -ef启动容器,打印ps -ef的输出

在docker run中,可以通过–entrypoint替换镜像中的入口程序,在Dockerfile中,应该至少有一条CMD或者ENTRYPOINT指令,如果同时定义了CMD和ENTRYPOINT则CMD会作为参数传递给ENTRYPOINT

FROMubuntu

ENTRYPOINT ["ps"]CMD ["-ef"]

//通过命令docker run --rm test启动容器,打印ps -ef的输出

你可能感兴趣的:(Dockerfile)