Dockerfile詳解
0. Dockerfile的做用
docker能夠根據Dockerfile中的指令來構建docker鏡像。Dockerfile是一個文本文件,其應當包含用戶想要構建一個鏡像的全部指令。docker
1. 構建鏡像的流程
真正執行構建任務的(就是讀取Dockerfile中的指令構建新的鏡像)是docker deamon。編程
- 執行 docker build -t images-name:tag .
- docker client會先將 當前目錄下的全部文件遞歸的發送給docker deamon
- docker deamon檢查Dockerfile是否有有語法錯誤,有錯誤則中止構建並將錯誤發送給docker client,沒有錯誤繼續執行
- docker deamon根據Dockerfile中的指令,一行一行的進行鏡像的構建
- 構建成功後,docker deamon自動清理context.
1. Dockerfile支持的指令
- FROM <image>[:tag] #表明着一個新的build stage的開始,並肯定這個build是基於哪一個鏡像來構建新的鏡像,在全部的指令中只有這個是必需要有的。
- ENV <key>=<value> | <key> <value> #配置環境變量,注意此配置會在container中生效。前一種能夠一行聲明多個環境變量,後一種一行一個。
- ARG <key>[=<value>] #變量,此變量的聲明週期與dockerfile構建過程一致,不會在container中生效。能夠經過build時添加--build-arg <key>=<value>進行覆蓋。注意:ARG時惟一能夠放到FROM以前的指令,當ARG放到FROM以前時,它的做用於只到FROM這一行。
- COPY src dest # 將src表明的文件或者文件夾拷貝到dest表明的目錄下。src支持通配符* ?
- ADD src dest #將src表明的文件或者文件夾或者網絡資源 拷貝到 dest表明的base-image的目錄下。src支持通配符 * ?
- RUN command #docker deamon在構建新的鏡像時,是經過先基於FROM的鏡像開啓一個container,而後在這個container裏執行。RUN指令就是是你想在container中執行的command。
- ENTRYPOINT ["executable", "param1", "param2"] | command param1 param2 # 將鏡像變成一個executable。推薦用CMD來代替。
- CMD ["executable", "param1", "parama2"] | ["param1", "param2"] | command param1 param2 # 最後有一個CMD指令纔有效,它表明這個image被用來建立container成功後執行的命令。第二種形式須要個ENTRYPOINT指令結合使用。
- LABEL <key>=<value> <key>=<value> #表明着這個image的元信息,好比此image的描述,版本,做者信息等等。
- EXPOSE port[/protocol] #經過這個image啓動的container將會監聽這些端口。可是注意這個只是在container內部監聽的端口,當你想經過主機訪問時須要在啓動container時用-p這進行映射。
- USER <user>[:<group>] | <UID>[:<GID>] #在這個指令以後的操做,以及運行container時,指定爲此用戶。
- WORKDIR /path #在此指令以後的操做,以及container的默認進入路徑都將時 /path目錄。
- VOLUME ['/path1', '/path2'] #基於此鏡像建立的container都將擁有VOLUME中指定的掛在目錄。注意映射的主機目錄沒法指定,有docker deamon自動生成,能夠經過docker inspect查看Mounts屬性。
2. Dockerfile編寫優化
1. 一個docker image只負責一個職責。當有多個服務時,請將服務分別docker化,而後組合使用這些docker images。緩存
2. 就像編程同樣,當一個字符串出現屢次時,請用ARG來聲明變量取代hard code。網絡
3. 拷貝文件到鏡像時,ADD負責網絡資源的拷貝,COPY負責本地文件的COPY。優化
4. 儘可能使用cache,docker在build鏡像時能夠利用緩存,緩存的原則時:當重複構建時,若是單個指令的內容沒有變化,則docker會默認使用cache。ui
5. 將相同變化頻率的RUN指令合併成一個。注意,必定要是相同變化頻率的RUN命令才能合併成一個,否則緩存的特性就沒法使用了。spa
6. 合理使用.dockerignore,減小images的體積。code
7. 儘可能使用CMD,VOLUME將image進行服務化。遞歸
8. 使用LABEL對image進行元信息的描述。資源
9. 單一服務的基礎鏡像如何能夠請使用alpine版本的鏡像來減小image的體積。