github编辑

ONBUILD 为他人作嫁衣裳

基本语法

ONBUILD <其它指令>

ONBUILD 是一个特殊的指令,它后面跟的是其它指令(如 RUN, COPY 等),这些指令在当前镜像构建时不会执行,只有当以当前镜像为基础镜像去构建下一级镜像时才会被执行。


为什么需要 ONBUILD

ONBUILD 主要用于制作语言栈基础镜像框架基础镜像

场景:维护 Node.js 项目

假设你有多个 Node.js 项目,它们的构建流程都一样:

  1. 创建目录

  2. 复制 package.json

  3. 执行 npm install

  4. 复制源码

  5. 启动应用

如果不使用 ONBUILD,每个项目的 Dockerfile 都要重复这些步骤,且通过 COPY 复制文件时,基础镜像无法预知子项目的文件名。

使用 ONBUILD 的解决方案

基础镜像 (my-node-base)

子项目 Dockerfile


执行机制


常见使用场景

1. 自动处理依赖安装

2. 自动编译代码

3. 处理静态资源


注意事项

1. 继承性限制

ONBUILD 指令只会继承一次

  • 镜像 A (含 ONBUILD)

  • 镜像 B (FROM A) -> 触发 ONBUILD

  • 镜像 C (FROM B) -> 不会再次触发 ONBUILD

2. 构建上下文

子镜像构建时,ONBUILD COPY . . 中的 . 指的是子项目的构建上下文,而不是基础镜像的上下文。

3. 不允许级联

ONBUILD ONBUILD 是非法的。你不能写 ONBUILD ONBUILD COPY ...

4. 可能会导致构建失败

由于 ONBUILD 实际上是在子镜像中执行指令,如果子项目的上下文不满足要求(例如缺少 package.json),会导致子镜像构建失败,且错误信息可能比较隐晦。


最佳实践

1. 命名规范

建议在镜像标签中添加 -onbuild 后缀,明确告知使用者该镜像包含触发器。

2. 避免执行耗时操作

尽量不要在 ONBUILD 中执行过于耗时或不确定的操作(如更新系统软件),这会让子镜像构建变得缓慢且不可控。

3. 清理工作

如果 ONBUILD 指令产生了临时文件,最好在同一个指令链中清理,或者提供机制让子镜像清理。


本章小结

要点
说明

作用

定义在子镜像构建时执行的指令

语法

ONBUILD INSTRUCTION

适用

基础架构镜像(Node, Python, Go 等)

限制

只继承一次,不可级联

规范

建议使用 -onbuild 标签后缀

延伸阅读

最后更新于