[Day 07]: Dockerfile 初探



建構映像

Docker 提供一種透過設定檔來建立映像的方式
即以 Dockerfile建構映像,這種方式是將製作映像的動作全部寫入一個檔案之中

優點:獨立、透明、建構方式容易重複執行、可方便移植

Dockerfile

  • 沒有副檔名,為純粹的文字檔
  • 形式:

    • 註解:在 Dockerfile中,註解的開頭皆以 # 起頭
    • 指令:(通常以大寫為主,方便區分)
      • Instruction:指令名稱
      • Argument: 指令參數
    • 例外:某類特定參數的開頭也為 #
      # directive=value,為解析指令列,用以提供解析Dockerfile所需要的參數

Dockerfile 範例

使用Dockerfile建構映像

docker CLI提供docker build命令,按照dockerfile內容輕鬆建立對應的映像

* docker build ~/Redis

// 建立 Redis映像
// build所接收的參數,必須為存放dockerfile的 「目錄」
//若存放 dockerfile的檔名非稱為"dockerfile",則加入參數 -f 放入目標路徑

docker會根據dockerfile建立映像時的每個步驟都產生一個映像,在建立映像時,docker會先在本地端查看使否已有該映像,若已存在則直接使用;這種逐一產生映像的方式對應了先前所說的映像中的分層結構,每層都是上一層的提交~

若不想要有太多層映像,可善用 && 將指令合併

建立映像時,必須指定映像的名稱和標籤

* docker build -t Kevin/redis:latest ~/Redis

// -t, tag

dockerfile指令

From

  • 用來指定建置的映象是基於哪個映像而來,這樣就不必每個映像都從頭開始建構
* FROM <Image>
* FROM <Image>:<Tag>
* FROM <Image>@<digest>

Maintainer

  • 提供映像的作者資訊
* MAINTAINER <Name>

Run

  • 即跑指令,為dockerfile中最常用的指令,指令有兩種模式
* RUN command param1 param2 ...                 // 1.
* RUN ["executable","param1","param2",...]      // 2.

指令1表示,建構映像時,實際上是以Shell來執行操作,

例如: RUN mkdir data 會是以 /bin/sh -c mkdir data

為何必須由Shell來操作呢?重點是:支援換列,可以使用「\」以拆解命令

* RUN apt-get install -y \
           file \
           g++ \
           gcc \
           make \
           curl \
           libc-dev \
           ...

而指令2會在命令和參數包在雙引號內,若某些基礎映像沒有使用Shell,這個指令模式則派上用場

* RUN ["/bin/bash", "-c","echo hello"]

Workdir

  • 用來切換建構過程的工作目錄
* WORKDIR /usr
// 可使用絕對目錄或相對目錄
* WORKDIR local
  • 亦允許使用環境變數
* ENV BASEDIR /project
* WORKDIR $BASEDIR/www

Onbuild

  • 特殊指令,可攜帶另一道指令
  • 可以看成一個觸發器,onbuild 所接的指令不會在建構時被執行
  • 但若其他Dockerfile 把此映像作為基礎映像並建置時,在執行完FORM指令後,所有透過Onbuild指令設定的指令將被觸發
* ONBUILD  INSTRUCTION arguments

Add

  • 建構映像時,常常需要將一些設定檔、執行腳本匯入映像的建置過程,此時就可以透過add指令將檔案從外部傳遞到映像內部
* ADD <src> .. <dest>
* ADD ["<src>",..."<dest>"]
// 將 src 目錄中的檔案 複製到 dest 映像的目標路徑

Copy

  • 此為另一種引入檔案的方式
* COPY <src>...<dest>
* COPY ["<src>",..."<dest>"]

CMD

  • dockerfile中可透過CMD指令來指定由映像建立的容器內的主體程式
* CMD ["executable","param1","param2",...]
* CMD ["param1","param2",...]
* CMD command param1 param2 ...

Entrypoint

  • 映像內應用程式運作時,多少都會有系統服務以及其他程式的支援
  • CMD啟動服務後,啟動支援服務的命令和主程式的命令混雜十分混亂
  • 透過ENTRYPOINT負責主程式執行前的準備工作
* ENTRYPOINT ["executable","param1","param2",...]
* ENTRYPOINT command param1 param2 ....

ENTRYPOINT指定的命令,都不會在容器啟動時執行,而是把這些命令作為參數傳入ENTRYPOINT指令列出的程式當中

Expose

  • 容器間的通訊必須透過docker來轉發
  • 若應用程式允許被其他映像存取它所提供的連接埠,則需列出對外開放的port號
* EXPOSE <port> [<port>...]

ENV

  • 設定環境變數
* ENV <key> <value>
* ENV <key>=<value>...

以上則為dockerfile 語法初探
7 天帶你對docker有基本認識
這 7天系列文,也算是小弟對 docker研究 7天下來的筆記
資訊若有誤,懇請糾正 <(_ _)>


參考資料

[1]
https://zhuanlan.zhihu.com/p/33366306

#docker #dockerfile #虛擬化技術







你可能感興趣的文章

Nand2tetris第二週心得

Nand2tetris第二週心得

The Wonders of Watchessy: Navigating the Maze of Mechanical Mastery

The Wonders of Watchessy: Navigating the Maze of Mechanical Mastery

DE2_115(DAY4)以niosii去控制板子上的LCD panel

DE2_115(DAY4)以niosii去控制板子上的LCD panel






留言討論