2017-07-20 206 views
0

我想在應用程序的官方Docker基礎映像中包含並啓用一些自定義插件。Dockerfile中的循環/迭代

下面是目錄結構的樣子;

. 
+-- Dockerfile 
+-- plugins 
| +-- plugin_1 
| +-- plugin_2 
| +-- plugin_3 
| +-- ... 
| +-- plugin_n 

Dockerfile如下所示,如果我需要包括插件plugin_1plugin_3plugin_7plugin_8;

FROM myapp_officialimage 

COPY plugins/plugin_1/* /usr/lib/myapp/plugins/ 
RUN myapp-plugins.sh enable plugin_1 

COPY plugins/plugin_3/* /usr/lib/myapp/plugins/ 
RUN myapp-plugins.sh enable plugin_3 

COPY plugins/plugin_7/* /usr/lib/myapp/plugins/ 
RUN myapp-plugins.sh enable plugin_7 

COPY plugins/plugin_8/* /usr/lib/myapp/plugins/ 
RUN myapp-plugins.sh enable plugin_8 

CMD ["myapp-start.sh"] 

問題是,是否有可能重複/遍歷一個列表,以消除上述樣板?

例如,像下面這樣的Dockerfile會更乾淨,更易於維護;

FROM myapp_officialimage 

ENV CUSTOM_PLUGIN_LIST="plugin_1 plugin_3 plugin_7 plugin_8" 

for plugin in $CUSTOM_PLUGIN_LIST; \ 
do \ 
    COPY plugins/$plugin/* /usr/lib/myapp/plugins/ \ 
    RUN myapp-plugins.sh enable $plugin \ 
done 

CMD ["myapp-start.sh"] 
+2

這將爲每個插件在圖像中創建兩個圖層。你不能用shell腳本來做到這一點嗎?那將是一個'RUN'。 – Grimmy

+0

這些插件可以以某種形式下載爲包嗎?然後,您將製作需求清單並將軟件包下載到映像中。 – Grimmy

+0

'docker build'發生在構建服務器上,而構建的映像將在生產環境中執行。生產中的主機不包括'plugins'目錄,生產網絡無法訪問下載插件文件。我需要在編譯和構建時間之前將這些插件捆綁在一起,然後將生成的圖像發佈到生產環境中。 –

回答

0

在你的情況我會準備一個新的插件與安裝它們(可能產生的或手工)腳本一起文件夾中。將真實的插件文件夾添加到.dockerignore。然後,您複製新文件夾並運行安裝腳本。這也減少了在開始構建之前上傳到Docker的上下文的大小。無論如何,你都是親自挑選依賴關係,所以事先做好工作(在你之前build)應該可以正常工作。

在構建系統,你,你應該這樣做:

collect_plugins.sh # Creates the new plugin folder and install script 
docker build <params> 

兩層便可設爲:

COPY plugins_selected/ /usr/lib/myapp/plugins/ 
RUN /usr/lib/myapp/plugins/install.sh 

如果你準備要發送到泊塢窗就會使上下文Dockerfile更簡單(一件好事)。我們只是在build之前解決問題。

通常使用包管理器通過網絡獲取依賴關係,或者只需通過http下載它們。像你在做的那樣將它們複製到構建上下文中並不一定是錯誤的,但它會變得更加尷尬。

讓我們來看看docker如何處理Dockerfile(略微模仿)。

當您使用build時,docker會將上下文中的所有文件上傳到碼頭引擎(.dockerignore中提及的路徑除外)並開始處理Dockerfile。目的是生成代表最終映像的文件系統層。

當您執行像RUN這樣的操作時,docker實際上會啓動一個容器來執行命令,然後將生成的圖層添加到圖像中。生產中唯一實際運行的是您在CMDDockerfile末尾指定的或ENTRYPOINT

儘量創建儘可能少的圖層。

dockerfile best practices guide covers the basics