Dockerfile使用多階段構建 翻譯自官網

2021-08-27 05:04:39 字數 3912 閱讀 4401

6分鐘

多階段構建是守護程式和客戶端上需要docker 17.05或更高版本的新功能。多階段構建對於那些努力優化dockerfiles同時使其易於閱讀和維護的人來說非常有用。

致謝:特別感謝alex ellis批准使用他的部落格文章 生成器模式與docker 中的多階段構建作為以下示例的基礎。

構建影象最具挑戰性的一點是保持影象尺寸不變。dockerfile中的每條指令都為影象新增了乙個圖層,您需要記住在移動到下一層之前清理任何不需要的工件。為了編寫乙個真正高效的dockerfile,傳統上需要使用shell技巧和其他邏輯來保持層盡可能小,並確保每個層都具有前一層所需的工件而不是其他任何東西。

實際上,有乙個dockerfile用於開發(包含構建應用程式所需的所有內容),以及用於生產的精簡版dockerfile,它只包含您的應用程式以及執行它所需的內容。這被稱為「建造者模式」。維護兩個dockerfiles並不理想。

這裡有乙個例子dockerfile.builddockerfile它遵守上面建造者模式:

請注意,此示例還run使用bash&&運算子人為壓縮兩個命令,以避免在影象中建立其他圖層。這很容易出錯並且難以維護。例如,插入另乙個命令很容易,忘記使用該\字元繼續該行。

多階段構建大大簡化了這種情況!

對於多階段構建,您可以from在dockerfile中使用多個語句。每條from指令可以使用不同的基礎,並且每個指令都開始構建的新階段。您可以選擇性地將工件從乙個階段複製到另乙個階段,從而在最終影象中留下您不想要的所有內容。為了說明這是如何工作的,讓我們調整上一節中的dockerfile以使用多階段構建。

您只需要單個dockerfile。您也不需要單獨的構建指令碼。只要執行docker build

$ docker build -t alexellis2/href-counter:latest .

最終結果是與以前相同的微小生產影象,複雜性顯著降低。您不需要建立任何中間影象,也不需要將任何工件提取到本地系統。

它是如何工作的?第二from條指令以alpine:latest影象為基礎開始乙個新的構建階段。該copy --from=0行僅將前一階段的構建工件複製到此新階段。go sdk和任何中間工件都被遺忘,而不是儲存在最終影象中。

預設情況下,階段未命名,您可以通過整數來引用它們,第一from條指令從0開始。但是,您可以通過asfrom指令中新增乙個來命名您的階段。此示例通過命名階段並使用copy指令中的名稱來改進前乙個示例。這意味著即使dockerfile中的指令稍後重新排序,copy也不會中斷。

構建映像時,不一定需要構建整個dockerfile,包括每個階段。您可以指定目標構建階段。以下命令假定您使用的是前乙個dockerfile但在名為的階段停止builder

$ docker build --target builder -t alexellis2/href-counter:latest .

一些可能非常強大的場景是:

使用多階段構建時,您不僅可以從先前在dockerfile中建立的階段進行複製。您可以使用該copy --from指令從單獨的映像進行複製,使用本地映像名稱,本地或docker登錄檔中可用的標記或標記id。如有必要,docker客戶端會提取影象並從那裡複製工件。語法是:

copy --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf

影象,容器,最佳實踐,多階段,多階段

Dockerfile多階段構建

多階段構建 之前的做法 在docker17.05版本之前,構建docker映象,通常採用兩種方式 1.全部放入乙個dockerfile 一種方式是將所有的構建過程全都包含在乙個dockerfile中,包括專案及其依賴庫的編譯 測試 打包流程,這裡會帶來的一些問題 映象層次多,映象體積較大,部署時間變...

Dockerfile多階段構建

我們在構建docker映象時,希望最後得到的映象越小越好,但是在構建時,總是會用到各種各樣複雜的環境,大部分都是臨時環境,只是為了生成對應的目標程式。比如我們經常會在opencv環境下編譯影象處理類程式,但其實目標程式只需要用的之前生成的子程式就行,不需要引入中間用到的環境。這裡我們就能用到dock...

Dockerfile 多階段構建

之前的做法 在 docker 17.05 版本之前,我們構建 docker 映象時,通常會採用兩種方式 一種方式是將所有的構建過程編包含在乙個 dockerfile 中,包括專案及其依賴庫的編譯 測試 打包等流程,這裡可能會帶來的一些問題 dockerfile 特別長,可維護性降低 映象層次多,映象...