Dockerfile参考(16) – ONBUILD向镜像添加触发指令

格式:

  1. ONBUILD [INSTRUCTION]

ONBUILD指令向镜像添加稍后要执行的触发指令,该触发指令在该镜像作为另一个镜像构建的base镜像时执行。触发指令在另一个镜像构建的Dockerfile的FROM指令后马上执行,就像FROM指令后插入触发指令一样。
任何的构建指令都可以注册为触发指令。
如果你正在构建的镜像会作为构建其它镜像的base镜像时,ONBUILD会有用,例如一个应用程序的构建环境或者可能需要用户自定义配置的daemon。
例如,如果你的镜像是一个可重复使用的Python应用程序镜像,你将需要把应用程序源码添加到指定的目录,和有可能需要在添加代码之后执行脚本启动应用程序。你不能仅仅的在base镜像中调用ADD和RUN,因为这时还没有应用程序源代码,并且每个应用程序配置都可能不一样。你可以简单地为应用程序开发者提供一个样本Dockerfile来复制粘贴到它们的应用程序,不过这个比较低效,容易出错和难以更新,因为它与应用程序特定代码混合了。
解决方案是使用ONBUIL来注册一个在下一个镜像构建时执行的高级指令。
下面是它的工作原理:
1.当镜像构建程序遇到ONBUILD指令时,构建程序把这个触发器添加到正在构建的镜像元数据中。这个ONBUILD指令不会影响到当前镜像的构建过程。
2.在完成构建镜像后,在关键词OnBuild下,所有的触发器明显地存储到了镜像。之后也可以使用docker inspect来查看它们。
3.之后其它镜像构建可以会用到上面的镜像作为base镜像,这个可以直接使用FROM引入base镜像。在构建程序执行Dockerfile中的FROM指令时,其中部分处理过程查找ONBUILD触发器,并按原来注册的顺序来执行触发指令。如果任何的一个触发器失败了,FROM指令将中断,反过来导致构建失败。如果所有的触发器指令执行成功,FROM指令就执行完成了,构建继教执行FROM后的指令。
4.构建新镜像完成时会清除触发器,也就是使用带触发器镜像作为base镜像构建新镜像不会继承它的触发器。
例如base镜像的Dockerfile如下,镜像名称为baseimg:

  1. [...]
  2. ONBUILD ADD . /app/src
  3. ONBUILD RUN /usr/local/bin/python-build --dir /app/src
  4. [...]

然后下面是构建新镜像的Dockerfile,镜像名称newimg:

  1. FROM baseimg
  2. [...]

当构建newimg镜像时,在构建程序执行FROM baseimg指令时,会依次执行baseimg注册的触发指令ADD . /app/src和RUN /usr/local/bin/python-build –dir /app/src,相当于在FROM baseimg指令后面自动添加了这两个指令。

标签:Docker 发布于:2019-11-19 20:53:55