为什么我应该使用Docker ONBUILD?

3

1. 带有 ONBUILD 的场景

基本的Dockerfile

FROM ubuntu:latest
RUN apt-get update && apt-get install python3

ONBUILD COPY test.py test.py

显然,当我们构建上述Dockerfile(test-image:latest)时,COPY不会受到影响。(即未复制test.py)

现在是onbuild Dockerfile

FROM test-image:latest

现在,当我们构建上述Dockerfile时,COPY会生效,复制test.py

2. 没有使用ONBUILD的情况

我可以不使用ONBUILD来实现同样的功能。

基本Dockerfile

FROM ubuntu:latest
RUN apt-get update && apt-get install python3

以上Dockerfile构建Docker镜像,其中包含python3 (test-image2:latest)。

现在是子Docker镜像的Dockerfile

FROM test-image2:latest
COPY test.py /test.py

所以,我的问题是,为什么应该使用 ONBUILD 或何时应该使用?是否存在性能差异?
2个回答

3
通常情况下,您不应该使用ONBUILD。让后面的Dockerfile FROM行做一些与仅仅包含其内容不同的事情,违反了最小惊奇原则。
如果你试图在ONBUILD中执行的操作类似于RUN或ENV指令,从语义上讲,在基础镜像或派生镜像中执行都没有区别。如果在基础镜像中执行(只执行一次),而不是在每次构建派生镜像时都执行,将会更有效率。
如果你尝试使用ONBUILD COPY ...,那么你正在试图强制一个特定的文件在运行docker build时存在于主机系统上,这对于消费者来说有点奇怪。 Docker的编写Dockerfiles的最佳实践指出:
“当把ADD或COPY放在ONBUILD中时要小心。如果新构建的上下文缺少被添加的资源,则“onbuild”镜像会发生灾难性失败。按照上述建议添加一个单独的标签可以通过允许Dockerfile作者进行选择来帮助缓解这种情况。”
正如该页面所指出的,如果你必须使用ONBUILD,你应该在镜像标签中加以说明,这样当你从该镜像构建Dockerfile时,就清楚地知道发生了一些奇怪的事情。 大多数当前的Docker Hub映像根本没有-onbuild变体,即使是对于通常具有极为公式化用法的tomcat等东西。

希望 Google 能有这种理念 :/ 他们的基础 GCP 镜像有 ONBUILD,可以运行 shell 脚本! - Charles Wood
如果不应该使用ONBUILD,为什么它还存在呢? - jtlz2

2
我认为答案很简单:当您的父镜像需要在多个子镜像中使用时,您希望使用ONBUILD,以便您可以:
  1. 避免重复
  2. 限制图像用户必须复制test.py

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接