建構映像
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天下來的筆記
資訊若有誤,懇請糾正 <(_ _)>