DOCKERFILE参数注解

Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。

一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

Dockerfile的指令是忽略大小写的,建议使用大写,使用 # 作为注释,每一行只支持一条指令,每条指令可以携带多个参数。

Dockerfile的指令根据作用可以分为两种:构建指令和设置指令。

  构建指令用于构建image,其指定的操作不会在运行image的容器上执行;
  设置指令用于设置image的属性,其指定的操作将在运行image的容器中执行。

可以在目录下创建.dockerignore文件,让Docker忽略路径下的文件和目录。

DockerFile的每一个指令都会新构建一层。

UnionFS是有最大层数限制的,比如AUFS,曾经是最大不能超过42层,现在是最大不能超过127层。所以,对于一些编译、软件的安装、更新等操作,无需分成好几层来操作,这样会使得镜像非常臃肿,拥有非常多的层,不仅仅增加了构建部署的时间,也很容易出错!!

指令描述格式
from

构建指令。

指定基础镜像,它是最重要的一个且必须为dokefile文件开篇的第一个非注释行,用于为镜像文件构建过程中指定基础镜像,后续的指令运行于此基准镜像所提供的运行环境

默认,docke会在本机寻找指定的镜像,找不到的时候则从docke hub registery拉取所需镜像,如果会找不到,则报错返回报错信息

如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指令。

DockerFile还存在一个特殊的镜像srcatch,这个镜像是一个虚拟的概念,并不实际存在,它表示一个空白的镜像。

如果你以scratch作为基础镜像,意味着你将不使用任何镜像为基础,接下来你所写的指令将作为第一层开始存在。不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见。如swarmcoreos/etcd。对Linux下静态编译的程序来说,并不需要其他操作提供其运行时支持,所需的一切库都在可执行文件里了,因此使用scratch作为基础,可以使镜像的体积更加小巧

from  <repository>[:<tag>]或者

from <repository>@<digest>

repository为基础镜像名称   tag为镜像标签为可选项,省略时为latest该image的最后修改的版本

MAINTAINER

构建指令

用于为docke提供作者信息,无顺序限制

用于将image的制作者相关的信息写入到image中。当我们对该image执行docker inspect命令时,输出中有相应的字段记录该信息。

此命令已经过时,可以使用LABEL maintainer=xxx 来替代,定义多个LABEL时,可以使用 【\】反划线来跨行

copy

用于从docker主机复制文件至创建的新镜像文件,但不会自动解压,不能从【 远端URL 】 复制。

目标路径是容器内的绝对路径,也可以是工作目录下的相对路径,工作目录可以使用WORKDIR指令进行指定。

使用COPY指令会将源路径的文件的所有元数据都拷贝,比如读、写、指定全选、时间变更等。

<源路径> 可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的 filepath.Match 规则

目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录

在使用该指令的时候还可以加上 --chown=<user>:<group> 选项来改变文件的所属用户及所属组。

文件复制准则:

1 COPY [--chown=<user>:<group>] <源路径>... <目标路径>
2 COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
add

构建指令

ADD指令和COPY的格式和性质基本一致,只不过是在COPY的基础上增加了一些功能。

如果是一个目录,那么会将该目录下的所有文件添加到container中,不包括目录;

如果<src>是文件且<dest>中不使用斜杠结束,则会将<dest>视为文件,<src>的内容会写入<dest>;

如果<src>是文件且<dest>中使用斜杠结束,则会<src>文件拷贝到<dest>目录下。

目标路径为一个URL时,会将其自动下载到目标路径下,但是其权限被自动设置成了600,如果这并不是你想要的权限,那么你还需要额外增加一层RUN命令进行更改,另外,如果下载的是一个压缩包,同样你还需要额外增加一层RUN命令进行解压缩。所以,在这种情况下,你还不如指定只用一层RUN,使用curl或者wget工具进行下载,并更改权限,然后进行解压缩,最后清理无用文件!

当你的源路径为压缩文件并且不想让Docker引擎将其自动解压缩,这个时候就不可以使用ADD命令,你可以使用COPY命令进行完成

run

构建指令。

每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行

RUN可以运行任何被基础image支持的命令。如基础image选择了ubuntu,那么软件管理部分只能使用ubuntu的命令

shell格式RUN <command> 或

exec格式RUN ["executable", "param1", "param2"]

前者将在 shell 终端中运行命令,即 /bin/sh -c;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"]

volume

设置指令

用于构建镜像时定义匿名卷。

容器存储层应该保持无状态化,容器运行时应尽量保持容器内不发生任何写入操作,对于需要保存动态数据的应用,其数据文件应该将其保存在数据卷中。

容器匿名卷目录指定可以通过docker run命令中指定-v参数来进行覆盖。

如果挂载点目录下此前存在文件,docker run命令会在卷挂载完成之后将此前的所有文件复制到新挂载的卷中

运行通过该Dockerfile生成image的容器,/tmp/data目录中的数据在容器关闭后,里面的数据还存在。

例如另一个容器也有持久化数据的需求,且想使用上面容器共享的/tmp/data目录,那么可以运行下面的命令启动一个容器:

docker run -t -i -rm -volumes-from container1 image2bash

其中:container1为第一个容器的ID,image2为第二个容器运行image的名字。

  • VOLUME <路径>
  • VOLUME [“<路径1>”, “<路径2>”, …]
expose

设置指令

EXPOSE指令是声明运行时容器服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。

在Dockerfile中这样声明有两个好处:一个是帮助镜像使用者更好的理解这个镜像服务的守护端口,另一个作用则是在运行时使用随机端口映射时,也就是docker run -p命令时,会自动随机映射EXPOSE端口。

要将EXPOSE和在运行时使用-p <宿主>:<容器端口>区分开来,-p是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而EXPOSE仅仅是声明端口使用什么端口而已,并不会自动在宿主进行端口映射

EXPOSE指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用-p选项。

EXPOSE 端口号

EXPOSE 端口号/协议

默认协议为TCP

env

设置指令

指定环境变量,它可以被其后的add、copy等调用

可以通过docker inspect查看这个环境变量,也可以通过在docker run --env key=value时设置或修改环境变量

如果你要设置多个环境变量,为了美观,你可以使用\来进行换行。多个环境变量的隔开,使用空格进行隔开的,如果某个环境变量的值是由一组英文单词构成,那么你可以将其使用""进行圈起来

值得注意的是,如果你想通过CMD或者ENTRYPOINT指令的exec格式来打印环境

CMD ["echo", $MODE]

CMD ["echo", "$MODE"]

上面这样都是不能正确输出环境变量的值的,你可以改成exec格式来执行shell命令,如下

CMD ["sh", "-c", "echo $MODE"]

调用格式$name或者${name}

wokrdir

设置指令

使用WORKDIR指令来制定工作目录(或者称为当前目录),以后各层操作的当前目录就是为指定的目录,如果该目录不存在,WORKDIR会自动帮你创建目录

WORKDIR指令可以通过docker run命令中的-w参数来进行覆盖

user

设置指令

指令用于将会用以什么样的用户去运行默认为root

可以指定用户名或者UID,组名或者GID,或者两者的结合

USER指令可以在docker run命令中的-u参数进行覆盖

后续的 RUN 也会使用指定用户。

当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres。要临时获取管理员权限可以使用 gosu,而不推荐 sudo

healthcheck

告诉Docker该如何判断容器的状态是否正常,这是1.12引入的新指令

在没有HEALTHCHECK指令之前,Docker引擎只可以通过容器内主进程是否退出来判断容器状态是否异常。很多情况下这没有问题,但是如果程序进入了死锁状态,或者死循环状态,应用进程并不退出,但是该容器已经无法继续提供服务了。在1.12之前,Docker引擎不会检测到容器的这种状态,从而不会重新调度,导致可能容器已经无法提供服务了却仍然还在接收用户的请求。

HEALTHCHECK指令只可以出现一次,如果有多个HEALTHCHECK指令,那么只有最后一个才会生效

HEALTHCHECK [options] CMD <命令>:检查容器健康状态的命令

HEALTHCHECK NONE:如果基础镜像有健康检查指令,这一行将会屏蔽掉其健康检查指令

HEALTHECHECK支持下列选项:

     –interval=<间隔>:两次检查的时间间隔,默认为30s

     –timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查将会判定                                        为失败,默认为30s

      –retries=<次数>:当连续失败指定次数之后,则将容器状态视为unhealthy,默认为3次

onbuildONBUILD是一个特殊的指令,它后面跟着的是其他指令,比如COPYRUN等,而这些命令在当前镜像被构建时,并不会被执行。只有以当前镜像为基础镜像去构建下一级镜像时,才会被执行ONBUILD <其他指令>
shell

指定Dockerfile中 【 shell form 】命令的默认shell。

Linux中默认shell为 【 “/bin/sh”, “-c”】

arg

构建参数ARGENV指令一样,都是设置环境变量。与之不同的是,ARG设置的环境变量只是在镜像构建时所设置的,在将来容器运行时是不会存在这些环境变量的。但是不要因此就用ARG来保存密码之类的信息,因为通过docker history还是能够看得到的。ARG指令与ENV指令的使用类似

ARG构建参数可以通过docker run命令中的--build-arg参数来进行覆盖

cmd

设置指令。

Docker不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,就需要指定运行的程序及参数。CMD就是指定默认的容器主进程的启动命令的

每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。

如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令

这里边包括参数的一定要用双引号,就是",不能是单引号。千万不能写成单引号。

原因是参数传递后,docker解析的是一个JSON array

一些命令在加上sh -c之后,有可能会发生意想不到的错误,因此在Dockerfile中使用RUN指令时,更加推荐使用exec格式!最后需要牢记,使用docker run命令指定要执行的命令可以覆盖RUN指令,如果我们的docker run中指定了我们将要执行的命令,并且在Dockerfile中也指定了CMD命令

exec格式CMD ["executable","param1","param2"] 

使用 exec 执行,推荐方式;

shell格式CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用。

CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数,如果CMD指令使用上面的形式,那么Dockerfile中必须要有配套的ENTRYPOINT

entrypoint

设置指令

指定容器运行程序及参数

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。

每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效

ENTRYPOINT也更加推荐使用exec格式,ENTRYPOINTdocker run命令中同样也可以进行指定,只不过比CMD指令来的繁琐一些,需要指定--entrypoint参数。同样,在docker run命令中指定了--entrypoint参数的话,会覆盖Dockerfile中ENTRYPOINT上的指令。

该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。

当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖,只有最后一个CMD或者ENTRYPOINT有效。

CMDecho “Hello, World!” 

ENTRYPOINT ls -l 

另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分;

ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数。

CMD ["-l"

ENTRYPOINT ["/usr/bin/ls"

exec格式ENTRYPOINT ["executable", "param1", "param2"]

shell格式ENTRYPOINT command param1 param2(shell中执行)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凤舞飘伶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值