Dockerfile ONBUILD指令

zer*_*ing 45 docker

我在docker文档中读到了如何使用ONBUILD指令,但它根本不清楚.
有人可以向我解释一下吗?

Mar*_*nor 49

ONBUILD指令是自动化您所选择的软件堆栈的构建是非常有用的.

Maven的容器被设计成编译Java程序.奇怪的是,你所有项目的Dockerfile需要做的是引用包含ONBUILD intructions的基础容器:

FROM maven:3.3-jdk-8-onbuild
CMD ["java","-jar","/usr/src/app/target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar"]
Run Code Online (Sandbox Code Playgroud)

基本图像的Dockerfile告诉所有人

FROM maven:3-jdk-8

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ONBUILD ADD . /usr/src/app

ONBUILD RUN mvn install
Run Code Online (Sandbox Code Playgroud)

有一个安装了Java和Maven的基本映像,以及一系列复制文件和运行Maven的指令.

以下答案给出了一个Java示例


jpe*_*erl 12

正如docker 文档所述

ONBUILD 指令将一个触发指令添加到图像中,以便稍后在图像用作另一个构建的基础时执行。触发器将在下游构建的上下文中执行,就好像它是在下游 Dockerfile 中的 FROM 指令之后立即插入的一样。

那是什么意思呢?让我们以这个 Nodejs Dockerfile 为例:

FROM node:0.12.6

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ONBUILD COPY package.json /usr/src/app/
ONBUILD RUN npm install
ONBUILD COPY . /usr/src/app

CMD [ "npm", "start" ]
Run Code Online (Sandbox Code Playgroud)

在您自己的 Dockerfile 中,当您执行此操作时,FROM node:0.12.6-onbuild您将获得一个映像,这意味着该build命令已经运行,因此指令也已执行,但是除了以ONBUILD. 这些已被推迟到另一个时间,当下游构建(当您的图像从您自己的 Dockerfile 构建时)使用此图像作为基础 ( FROM node:0.12.6-onbuild)。

您不能只调用ADDand RUNnow,因为您还没有访问应用程序源代码的权限,而且每个应用程序构建都会有所不同。

这是正确的!包含 onbuild 指令的映像不是在您的机器上构建的,因此它还无法访问package.json.

然后,当您构建自己的 Dockerfile 时,在执行文件中的任何指令之前,构建器将查找ONBUILD触发器,这些触发器在构建时已添加到父映像的元数据中。

这样就免去了您自己执行这些命令的麻烦,就好像这些命令是写在您自己的 Dockerfile 中一样。

最后,他们补充说:

您可以简单地为应用程序开发人员提供一个样板 Dockerfile 以将其复制粘贴到他们的应用程序中,但由于它与特定于应用程序的代码混合在一起,因此效率低下、容易出错且难以更新。

问题是,如果这些指令在样板 Dockerfile 中被修改,你将不得不在你的 Dockerfile 中修改它们。但多亏了ONBUILD指令,我们不必担心。