onbuild 是为下游镜像预埋构建动作的 legacy 指令,仅在子镜像构建时 from 后自动执行一次,适用于统一目录创建、依赖校验等构建期共性操作,现代项目应优先采用多阶段构建或标准化脚本替代。

ONBUILD 指令不是用来构建当前镜像的,而是为下游镜像“预埋”构建动作——它在子镜像执行 FROM 后、其他指令前自动触发,适合统一企业内微服务的构建流程。
ONBUILD 的正确触发时机与行为
它只在子镜像构建阶段生效,且严格位于 FROM 指令之后、其余指令之前。当前镜像自身构建时,ONBUILD 完全不执行。例如:
- 基础镜像 A 中写有
ONBUILD RUN mkdir -p /app/src,构建 A 时该命令不会运行 - 子镜像 B 的 Dockerfile 以
FROM A开头,docker build B 时,mkdir -p /app/src会自动执行一次 - 若 B 构建成功,C 再
FROM B,A 中定义的 ONBUILD 不会再次触发(无嵌套传递)
典型合规用法:聚焦构建期共性动作
ONBUILD 只适用于所有继承者都必须一致执行的构建期操作,不涉及运行时行为。常见安全用法包括:
- 自动创建标准化目录结构:
ONBUILD RUN mkdir -p /app/config /app/logs - 强制复制并校验依赖清单后安装:
ONBUILD COPY package.json . && ONBUILD RUN npm ci --only=production - 注入构建元数据:
ONBUILD ENV BUILD_REF=$BUILD_COMMIT HASH BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) - 复制内部通用脚本并设权限:
ONBUILD COPY build-scripts/ /usr/local/bin/ && ONBUILD RUN chmod +x /usr/local/bin/*.sh
关键避坑点:避免隐式依赖与误用场景
ONBUILD 容易引发不可控行为,需严格约束使用边界:
- 基础镜像中未预装的工具(如 yarn、mvn),不能出现在 ONBUILD RUN 中
- 禁止用 ONBUILD 设置环境变量供 CMD 或 ENTRYPOINT 使用——这些是运行时逻辑,应由子镜像显式声明
- 不要把多条 ONBUILD 拆开写成独立指令,应合并为单条或改用显式 COPY + RUN 组合,保证语义清晰
- 不推荐基于已含 ONBUILD 的镜像再派生新基础镜像,优先从 openjdk:17-jre-slim、node:20-alpine 等官方精简镜像直接构建
现代替代建议:ONBUILD 已标记为 legacy
自 Docker 24.x 起,ONBUILD 被官方明确标记为 legacy 特性。新项目更推荐以下方式替代:
- 多阶段构建:用 builder 阶段完成编译和依赖安装,最终阶段仅保留运行时文件
- 标准化构建脚本 + ARG 参数:在基础镜像中提供通用 entrypoint.sh,并通过
--build-arg控制行为 - LABEL + 文档约定:用 LABEL 标注预期构建契约(如
LABEL com.example.build-requirement="package.json"),配合 CI 流程校验 - 模板化 Dockerfile(如通过 Helm、ytt 或自定义代码生成器)统一生成子镜像内容











