1. 程式人生 > >Dockerfile 指令 ONBUILD介紹

Dockerfile 指令 ONBUILD介紹

來源:https://www.cnblogs.com/51kata/p/5265107.html

ONBUILD指令可以為映象新增觸發器。其引數是任意一個Dockerfile 指令。

當我們在一個Dockerfile檔案中加上ONBUILD指令,該指令對利用該Dockerfile構建映象(比如為A映象)不會產生實質性影響。

但是當我們編寫一個新的Dockerfile檔案來基於A映象構建一個映象(比如為B映象)時,這時構造A映象的Dockerfile檔案中的ONBUILD指令就生效了,在構建B映象的過程中,首先會執行ONBUILD指令指定的指令,然後才會執行其它指令。

需要注意的是,如果是再利用B映象構造新的映象時,那個ONBUILD指令就無效了,也就是說只能再構建子映象中執行,對孫子映象構建無效。其實想想是合理的,因為在構建子映象中已經執行了,如果孫子映象構建還要執行,相當於重複執行,這就有問題了。

利用ONBUILD指令,實際上就是相當於建立一個模板映象,後續可以根據該模板映象建立特定的子映象,需要在子映象構建過程中執行的一些通用操作就可以在模板映象對應的dockerfile檔案中用ONBUILD指令指定。 從而減少dockerfile檔案的重複內容編寫。

 

我們來看一個簡單例子。

1、先編寫一個Dockerfile檔案,內容如下:

#test
FROM ubuntu
MAINTAINER hello
ONBUILD RUN mkdir mydir

利用上面的dockerfile檔案構建映象: docker build -t imagea .
利用imagea映象建立容器: docker run --name test1 -it imagea /bin/bash

我們發現test1容器的根目錄下並沒有mydir目錄。說明ONBUILD指令指定的指令並不會在自己的構建中執行。

2、再編寫一個新的Dockerfile檔案,內容 如下

#test
FROM imagea
MAINTAINER hello1

注意,該構建準備使用的基礎映象是上面構造出的映象imagea
利用上面的dockerfile檔案構建映象: docker build -t imageb .
利用imagea映象建立容器: docker run --name test2 -it imageb /bin/bash

我們發現test2容器的根目錄下有mydir目錄,說明觸發器執行了。 這個其實從構建imageb的輸出日誌就可看出。日誌如下:

複製程式碼

[email protected]:~/myimage$ docker build -t imageb .
Sending build context to Docker daemon 15.87 kB
Step 1 : FROM imagea
# Executing 1 build trigger...
Step 1 : RUN mkdir mydir
 ---> Running in e16c35c94b03
 ---> 4b393d1610a6
Removing intermediate container e16c35c94b03
Step 2 : MAINTAINER hello1
 ---> Running in c7b0312516ea
 ---> 0f63b8e04d82
Removing intermediate container c7b0312516ea
Successfully built 0f63b8e04d82

複製程式碼

我們可以看出,FROM指令執行之後,就立即執行的是觸發器(ONBUILD指令指定的指令)