在容器環境中,我們可以通過容器建立一個我們自定義過的鏡像,那麼我們是否可以直接通過基礎的鏡像直接自定義鏡像呢?答案當然是可以的,在 Docker 中我們可以從名為 <code>Dockerfile</code> 的檔案中讀取指令并且自動建構鏡像。在本文中,将介紹 Dockerfile 的基本文法以及基本知識。
Dockerfile 其實是一份文本文檔,裡面包含了使用者可以用來操作鏡像的一些指令。通過順序執行這些指令,最後得到一個自定義的鏡像,這有點類似于我們的 <code>shell script</code>。
接下來先看一個 Dockerfile 示例:
在上面我們可以看到 Dockerfile 中的一些指令,通過名稱我們也可以猜到這些指令大概是幹嘛的,其中有一些對檔案的操作,是以我們先來看看用于存放 Dockerfile 的這個目錄的目錄結構:
在目前目錄下執行以下指令建構鏡像:
然後用該鏡像啟動容器:
用浏覽器通路 <code>http://localhost:8080/</code> 即可看到部署的内容。
Dockerfile 支援 <code>FROM</code>, <code>RUN</code>, <code>CMD</code>, <code>LABEL</code>, <code>EXPOSE</code>, <code>ENV</code>, <code>ADD</code>, <code>COPY</code>, <code>ENTRYPOINT</code>, <code>VOLUME</code>, <code>USER</code>, <code>WORKDIR</code>, <code>ARG</code>, <code>ONBUILD</code>, <code>SHELL</code>等指令,這裡隻選擇常用的幾個進行講解,可結合上面的示例進行了解。其它的請自行查閱官方文檔。
<code>FROM</code> 指令用于指定要操作的基礎鏡像,因為在我們建構我們自己的鏡像的時候需要一個基礎鏡像。
文法:
其中 <code>[AS <name>]</code> 為指定一個名稱,在一個 Dockerfile 中多次使用 <code>FROM</code> 時如有需要,可用 <code>COPY --from=<name|index></code> 文法進行複制。
<code>RUN</code> 指令用于執行指令,并且是在新的一層上執行,并把執行後的結果送出,也就是生成新的一層。基于這個問題,我們在使用 <code>RUN</code> 指令時應該盡可能的把要執行的指令一次寫完,以減少最後生成的鏡像的層數。文法:
<code>CMD</code> 指令用于給容器啟動時指定一個用于執行的指令,例如上例中的 nginx 啟動指令。
<code>LABEL</code> 指令用于為鏡像指定标簽,可用 <code>docker inspect</code> 指令檢視。可用來代替被舍棄的 <code>MAINTAINER</code> 指令。文法:
<code>EXPOSE</code> 指令用于告訴 Docker 容器監聽的特殊端口,但是此時端口還沒有暴露給 host ,隻有當在運作一個容器顯式用參數 <code>-p</code> 或者 <code>-P</code> 的時候才會暴露端口。文法:
<code>ENV</code> 指令用于設定環境變量。文法:
<code>ADD</code> 指令用于複制新檔案,目錄,遠端檔案到容器中。其中 <code><src></code> 可以為檔案,目錄,URL,若為可解壓檔案,在複制後會解壓。文法:
<code>COPY</code> 指令與 <code>ADD</code> 指令非常相似,但 <code>COPY</code> 比較直覺且簡單,它隻支援本地的檔案以及目錄的複制,不像 <code>ADD</code> 指令可以遠端擷取檔案并解壓。文法:
<code>ENTRYPOINT</code> 指令也跟 <code>CMD</code> 指令相似,用于指定容器啟動時執行的指令。當使用 <code>ENTRYPOINT</code> 指令時,可用 <code>CMD</code> 指令配合,這樣在啟動容器時,可以對 <code>CMD</code> 指令寫入的參數進行覆寫。文法:
樣例:
上面的 <code>-c</code> 參數可以在啟動時覆寫 <code>docker run -it --rm --name test top -H</code>。
如果要覆寫 <code>ENTRYPOINT</code> 指令則用 <code>--entrypoint</code> 參數啟動容器。
<code>VOLUME</code> 指令用于為容器建立一個挂載點,這個挂載點可以用來挂載 <code>本地檔案/檔案夾</code> 也可以用來挂載 <code>資料卷</code>。其中若在啟動一個新容器時沒有指定挂載目錄,則會自動建立一個資料卷,當容器被銷毀時,資料卷如果沒有被其它容器引用則會被删除。文法:
<code>USER</code> 指令用于設定執行 <code>RUN</code>, <code>CMD</code>, <code>ENTRYPOINT</code> 等指令的使用者以及使用者組。預設為 <code>root</code> 使用者。文法:
<code>WORKDIR</code> 指令用于設定 <code>RUN</code>, <code>CMD</code>, <code>ENTRYPOINT</code>, <code>COPY</code>, <code>ADD</code> 等指令的工作目錄。文法:
本文從一個具體的例子出發,講述了如何利用 Dockerfile 建構鏡像,然後解釋了 Dockerfile 檔案中的指令的文法,有關更多内容可通路官方文檔。
<a href="https://docs.docker.com/engine/reference/builder/" target="_blank">Dockerfile reference</a>
原文釋出時間:2017-12-16