天天看點

Dockerfile最佳實踐(一)

Dockerfile使用簡單的文法來建構鏡像。下面是一些建議和技巧以幫助你使用Dockerfile。

Dockerfile的每條指令都會将結果送出為新的鏡像,下一個指令将會基于上一步指令的鏡像的基礎上建構,如果一個鏡像存在相同的父鏡像和指令(除了<code>ADD</code>),Docker将會使用鏡像而不是執行該指令,即緩存。

為了有效地利用緩存,你需要保持你的Dockerfile一緻,并且盡量在末尾修改。我所有的Dockerfile的前五行都是這樣的:

更改<code>MAINTAINER</code>指令會使Docker強制執行<code>RUN</code>指令來更新apt,而不是使用緩存。

是以,我們應該使用常用且不變的Dockerfile開始(譯者注:上面的例子)指令來利用緩存。

除非你正在用Docker做實驗,否則你應當通過<code>-t</code>選項來<code>docker build</code>新的鏡像以便于标記建構的鏡像。一個簡單的可讀标簽将幫助你管理每個建立的鏡像。

注意,始終通過<code>-t</code>标記來建構鏡像。

兩個Docker的核心概念是可重複和可移植。鏡像應該可以運作在任何主機上并且運作盡可能多的次數。在Dockerfile中你有能力映射私有和公有端口,但是你永遠不要通過Dockerfile映射公有端口。通過映射公有端口到主機上,你将隻能運作一個容器化應用程式執行個體。(譯者注:運作多個端口不就沖突啦)

如果鏡像的使用者關心容器公有映射了哪個公有端口,他們可以在運作鏡像時通過<code>-p</code>參數設定,否則,Docker會自動為容器配置設定端口。

切勿在Dockerfile映射公有端口。

<code>CMD</code>和<code>ENTRYPOINT</code>指令都非常簡單,但它們都有一個隐藏的容易出錯的“功能”,如果你不知道的話可能會在這裡踩坑,這些指令支援兩種不同的文法。

這看起來好像沒什麼問題,但仔細一看其實兩種方式差距很大。如果你使用第二個文法:<code>CMD</code>(或<code>ENTRYPOINT</code>)是一個數組,它執行的指令完全像你期望的那樣。如果使用第一種文法,Docker會在你的指令前面加上<code>/bin/sh -c</code>,我記得一直都是這樣。

如果你不知道Docker修改了<code>CMD</code>指令,在指令前加上<code>/bin/sh -c</code>可能會導緻一些意想不到的問題以及難以了解的功能。是以,在使用這兩個指令時你應當使用數組文法,因為數組文法會确切地執行你打算執行的指令。

使用CMD和ENTRYPOINT時,請務必使用數組文法。

這是Docker化Rethinkdb的所有配置檔案。在開始我們有标準的5行來確定基礎鏡像是最新的、端口的公開等。當<code>ENTRYPOINT</code>指令出現時,我們知道每次運作該鏡像,在<code>docker run</code>過程中傳遞的所有參數将成為<code>ENTRYPOINT</code>(<code>/usr/bin/rethinkdb</code>)的參數。

在Dockerfile中我還設定了一個預設<code>CMD</code>參數<code>--help</code>。這樣做是為了<code>docker run</code>期間如果沒有參數的傳遞,rethinkdb将會給使用者顯示預設的幫助文檔。這是你所期望的與rethinkdb互動相同的功能。

輸出

現在,讓我們帶上<code>--bind all</code>參數來運作容器。

就這樣,一個全面的可以通路db和管理控制台的Rethinkdb執行個體就運作起來了,你可以用與鏡像互動一樣的方式來與其互動。雖然簡單小巧但它的功能非常強大。

CMD和ENTRYPOINT 結合在一起使用更好。

我希望這篇文章可以幫助你使用Dockerfiles以及建構鏡像。Dockerfile是Docker的重要一部分,無論你是建構或是使用鏡像,它都非常簡單而且使用友善。我打算投入更多的時間來提供一個完整的、功能強大但簡單的解決方案來使用Dockerfile建構Docker鏡像。

本文轉自 h2appy  51CTO部落格,原文連結:http://blog.51cto.com/h2appy/1865358,如需轉載請自行聯系原作者