Dockerfile指令详解:ONBUILD 为他人作嫁衣裳
ONBUILD 為他人做嫁衣裳
格式:ONBUILD <其它指令>。
ONBUILD 是一個特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而這些指令,在當(dāng)前鏡像構(gòu)建時并不會被執(zhí)行。只有當(dāng)以當(dāng)前鏡像為基礎(chǔ)鏡像,去構(gòu)建下一級鏡像的時候才會被執(zhí)行。
Dockerfile 中的其它指令都是為了定制當(dāng)前鏡像而準(zhǔn)備的,唯有 ONBUILD 是為了幫助別人定制自己而準(zhǔn)備的。
假設(shè)我們要制作 Node.js 所寫的應(yīng)用的鏡像。我們都知道 Node.js 使用 npm 進(jìn)行包管理,所有依賴、配置、啟動信息等會放到 package.json 文件里。在拿到程序代碼后,需要先進(jìn)行 npm install 才可以獲得所有需要的依賴。然后就可以通過 npm start 來啟動應(yīng)用。因此,一般來說會這樣寫 Dockerfile:
FROM node:slim RUN mkdir /app WORKDIR /app COPY ./package.json /app RUN [ "npm", "install" ] COPY . /app/ CMD [ "npm", "start" ]把這個 Dockerfile 放到 Node.js 項(xiàng)目的根目錄,構(gòu)建好鏡像后,就可以直接拿來啟動容器運(yùn)行。但是如果我們還有第二個 Node.js 項(xiàng)目也差不多呢?好吧,那就再把這個 Dockerfile 復(fù)制到第二個項(xiàng)目里。那如果有第三個項(xiàng)目呢?再復(fù)制么?文件的副本越多,版本控制就越困難,讓我們繼續(xù)看這樣的場景維護(hù)的問題。
如果第一個 Node.js 項(xiàng)目在開發(fā)過程中,發(fā)現(xiàn)這個 Dockerfile 里存在問題,比如敲錯字了、或者需要安裝額外的包,然后開發(fā)人員修復(fù)了這個 Dockerfile,再次構(gòu)建,問題解決。第一個項(xiàng)目沒問題了,但是第二個項(xiàng)目呢?雖然最初 Dockerfile 是復(fù)制、粘貼自第一個項(xiàng)目的,但是并不會因?yàn)榈谝粋€項(xiàng)目修復(fù)了他們的 Dockerfile,而第二個項(xiàng)目的 Dockerfile 就會被自動修復(fù)。
那么我們可不可以做一個基礎(chǔ)鏡像,然后各個項(xiàng)目使用這個基礎(chǔ)鏡像呢?這樣基礎(chǔ)鏡像更新,各個項(xiàng)目不用同步 Dockerfile 的變化,重新構(gòu)建后就繼承了基礎(chǔ)鏡像的更新?好吧,可以,讓我們看看這樣的結(jié)果。那么上面的這個 Dockerfile 就會變?yōu)?#xff1a;
FROM node:slim RUN mkdir /app WORKDIR /app CMD [ "npm", "start" ]這里我們把項(xiàng)目相關(guān)的構(gòu)建指令拿出來,放到子項(xiàng)目里去。假設(shè)這個基礎(chǔ)鏡像的名字為 my-node 的話,各個項(xiàng)目內(nèi)的自己的 Dockerfile 就變?yōu)?#xff1a;
FROM my-node COPY ./package.json /app RUN [ "npm", "install" ] COPY . /app/基礎(chǔ)鏡像變化后,各個項(xiàng)目都用這個 Dockerfile 重新構(gòu)建鏡像,會繼承基礎(chǔ)鏡像的更新。
那么,問題解決了么?沒有。準(zhǔn)確說,只解決了一半。如果這個 Dockerfile 里面有些東西需要調(diào)整呢?比如 npm install 都需要加一些參數(shù),那怎么辦?這一行 RUN 是不可能放入基礎(chǔ)鏡像的,因?yàn)樯婕暗搅水?dāng)前項(xiàng)目的 ./package.json,難道又要一個個修改么?所以說,這樣制作基礎(chǔ)鏡像,只解決了原來的 Dockerfile 的前4條指令的變化問題,而后面三條指令的變化則完全沒辦法處理。
ONBUILD 可以解決這個問題。讓我們用 ONBUILD 重新寫一下基礎(chǔ)鏡像的 Dockerfile:
FROM node:slim RUN mkdir /app WORKDIR /app ONBUILD COPY ./package.json /app ONBUILD RUN [ "npm", "install" ] ONBUILD COPY . /app/ CMD [ "npm", "start" ]這次我們回到原始的 Dockerfile,但是這次將項(xiàng)目相關(guān)的指令加上 ONBUILD,這樣在構(gòu)建基礎(chǔ)鏡像的時候,這三行并不會被執(zhí)行。然后各個項(xiàng)目的 Dockerfile 就變成了簡單地:
FROM my-node是的,只有這么一行。當(dāng)在各個項(xiàng)目目錄中,用這個只有一行的 Dockerfile 構(gòu)建鏡像時,之前基礎(chǔ)鏡像的那三行 ONBUILD 就會開始執(zhí)行,成功的將當(dāng)前項(xiàng)目的代碼復(fù)制進(jìn)鏡像、并且針對本項(xiàng)目執(zhí)行 npm install,生成應(yīng)用鏡像。
總結(jié)
以上是生活随笔為你收集整理的Dockerfile指令详解:ONBUILD 为他人作嫁衣裳的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过Athens搭建go私服
- 下一篇: Dockerfile指令详解: CMD