Docker實戰-編寫Dockerfile
一、編譯映象
1. 編譯映象
Dockerfile
類似於Makfile
,使用者使用docker build
就可以編譯映象,使用該命令可以設定編譯映象時使用的CPU數量、記憶體大小、檔案路徑等
語法:
docker build [OPTIONS] PATH| URL| -
常見選項:
-t 設定映象的名稱和TAG,格式為name:tag
-f Dockerfile的名稱,預設為PATH/Dockerfile
例子:docker build -f ~/php.Dockerfile .
注意:PATH
是編譯映象使用的工作目錄,Docker Daemon
在編譯開始時,會掃描PATH
中的所有檔案,可以在編譯目錄中加入.dockerignore
過濾不需要的檔案
Docker Daemon
從Dockerfile
中順序讀取指令,生成一個臨時容器,在容器中執行指令,容器編譯成功後會提交作為映象層加入最終映象,為了加快編譯過程,Docker Daemon
採用了快取機制,如果在快取中找到了需要的中間映象則直接使用該映象而不生成臨時容器(編譯時可以使用選項–no-cache
選擇不使用快取)
2. dockerignore
檔案
編譯開始前,Docker Daemon
會讀取編譯目錄中的.dockerignore
檔案,忽略其中的檔案和目錄,在其中可以使用萬用字元(?代表一個字元,*代表零個或任意個字元),使用萬用字元時,總會出現那麼幾個例外,這時可以使用!+檔名,Docker Daemon
會讀取!後面的檔案
*/temp* 忽略PATH路徑下一級子目錄中以temp開頭的檔案和目錄,如PAHT/A/temp.txt
*/*/temp* 忽略PATH路徑下二級子目錄中以temp開頭的檔案和目錄,如PATH/A/B/temp.txt
*.md
!README.md 忽略所有md檔案,除了README.md
二、Dockerfile指令詳解
Dockerfile
由多條指令組成,每條指令在編譯映象時執行相應的程式完成某些功能,由指令+引數
組成,以逗號分隔,#
作為註釋起始符,雖說指令不區分大小寫,但是一般指令使用大些,引數使用小寫
指令:
FROM
功能描述:設定基礎映象
語法:
FROM < image>[:< tag> | @< digest>]
提示:映象都是從一個基礎映象(作業系統或其他映象)生成,可以在一個
Dockerfile
中新增多條FROM
指令,一次生成多個映象注意:如果忽略
tag
選項,會使用latest
映象
指令:MAINTAINER
功能描述:設定映象作者
語法:MAINTAINER < name>
指令:RUN
功能描述:
語法:RUN < command>
RUN [“executable”,”param1”,”param2”]
提示:RUN指令會生成容器,在容器中執行指令碼,容器使用當前映象,指令碼指令完成後,Docker Daemon會將該容器提交為一箇中間映象,供後面的指令使用
補充:RUN指令第一種方式為shell方式,使用/bin/sh -c < command>執行指令碼,可以在其中使用\將指令碼分為多行
RUN指令第二種方式為exec方式,映象中沒有/bin/sh或者要使用其他shell時使用該方式,其不會呼叫shell命令
例子:RUN source $HOME/.bashrc;\
echo $HOMERUN [“/bin/bash”,”-c”,”echo hello”] RUN [“sh”,”-c”,”echo”,”$HOME”] 使用第二種方式呼叫shell讀取環境變數
指令:CMD
功能描述:設定容器的啟動命令
語法:CMD [“executable”,”param1”,”param2”]
CMD [“param1”,”param2”]
CMD < command>
提示:CMD第一種、第三種方式和RUN類似,第二種方式為ENTRYPOINT引數方式,為entrypoint提供引數列表
注意:Dockerfile中只能有一條CMD命令,如果寫了多條則最後一條生效
指令:LABEL
功能描述:設定映象的標籤
延伸:映象標籤可以通過docker inspect檢視
格式:LABEL < key>=< value> < key>=< value> …
提示:不同標籤之間通過空格隔開
注意:每條指令都會生成一個映象層,Docker中映象最多隻能有127層,如果超出Docker Daemon就會報錯,如LABEL ..=.. <假裝這裡有個換行> LABEL ..=..合在一起用空格分隔就可以減少映象層數量,同樣,可以使用連線符\將指令碼分為多行
映象會繼承基礎映象中的標籤,如果存在同名標籤則會覆蓋
指令:EXPOSE
功能描述:設定映象暴露埠,記錄容器啟動時監聽哪些埠
語法:EXPOSE < port> < port> …
延伸:映象暴露埠可以通過docker inspect檢視
提示:容器啟動時,Docker Daemon會掃描映象中暴露的埠,如果加入-P引數,Docker Daemon會把映象中所有暴露埠匯出,併為每個暴露埠分配一個隨機的主機埠(暴露埠是容器監聽埠,主機埠為外部訪問容器的埠)
注意:EXPOSE只設定暴露埠並不匯出埠,只有啟動容器時使用-P/-p才匯出埠,這個時候才能通過外部訪問容器提供的服務
指令:ENV
功能描述:設定映象中的環境變數
語法:ENV < key>=< value>…|< key> < value>
注意:環境變數在整個編譯週期都有效,第一種方式可設定多個環境變數,第二種方式只設定一個環境變數
提示:通過{變數名}或者變數名使用變數,使用方式{變數名}時可以用{變數名:-default} ${變數名:+cover}設定預設值或者覆蓋值
ENV設定的變數值在整個編譯過程中總是保持不變的
指令:ADD
功能描述:複製檔案到映象中
語法:ADD < src>… < dest>|[“< src>”,… “< dest>”]
注意:當路徑中有空格時,需要使用第二種方式
當src為檔案或目錄時,Docker Daemon會從編譯目錄尋找這些檔案或目錄,而dest為映象中的絕對路徑或者相對於WORKDIR的路徑
提示:src為目錄時,複製目錄中所有內容,包括檔案系統的後設資料,但不包括目錄本身
src為壓縮檔案,並且壓縮方式為gzip,bzip2或xz時,指令會將其解壓為目錄
如果src為檔案,則複製檔案和後設資料
如果dest不存在,指令會自動建立dest和缺失的上級目錄
指令:COPY
功能描述:複製檔案到映象中
語法:COPY < src>… < dest>|[“< src>”,… “< dest>”]
提示:指令邏輯和ADD十分相似,同樣Docker Daemon會從編譯目錄尋找檔案或目錄,dest為映象中的絕對路徑或者相對於WORKDIR的路徑
指令:ENTRYPOINT
功能描述:設定容器的入口程式
語法:ENTRYPOINT [“executable”,”param1”,”param2”]
ENTRYPOINT command param1 param2(shell方式)
提示:入口程式是容器啟動時執行的程式,docker run中最後的命令將作為引數傳遞給入口程式
入口程式有兩種格式:exec、shell,其中shell使用/bin/sh -c執行入口程式,此時入口程式不能接收訊號量
當Dockerfile有多條ENTRYPOINT時只有最後的ENTRYPOINT指令生效
如果使用指令碼作為入口程式,需要保證指令碼的最後一個程式能夠接收訊號量,可以在指令碼最後使用exec或gosu啟動傳入指令碼的命令
注意:通過shell方式啟動入口程式時,會忽略CMD指令和docker run中的引數
為了保證容器能夠接受docker stop傳送的訊號量,需要通過exec啟動程式;如果沒有加入exec命令,則在啟動容器時容器會出現兩個程式,並且使用docker stop命令容器無法正常退出(無法接受SIGTERM訊號),超時後docker stop傳送SIGKILL,強制停止容器
例子:FROM ubuntu <換行> ENTRYPOINT exec top -b
指令:VOLUME
功能描述:設定容器的掛載點
語法:VOLUME [“/data”]
VOLUME /data1 /data2
提示:啟動容器時,Docker Daemon會新建掛載點,並用映象中的資料初始化掛載點,可以將主機目錄或資料卷容器掛載到這些掛載點
指令:USER
功能描述:設定RUN CMD ENTRYPOINT的使用者名稱或UID
語法:USER < name>
指令:WORKDIR
功能描述:設定RUN CMD ENTRYPOINT ADD COPY
指令的工作目錄
語法:WORKDIR < Path>
提示:如果工作目錄不存在,則Docker Daemon會自動建立
Dockerfile中多個地方都可以呼叫WORKDIR,如果後面跟的是相對位置,則會跟在上條WORKDIR指定路徑後(如WORKDIR /A WORKDIR B WORKDIR C,最終路徑為/A/B/C)
指令:ARG
功能描述:設定編譯變數
語法:ARG < name>[=< defaultValue>]
注意:ARG從定義它的地方開始生效而不是呼叫的地方,在ARG之前呼叫編譯變數總為空,在編譯映象時,可以通過docker build –build-arg < var>=< value>設定變數,如果var沒有通過ARG定義則Daemon會報錯
可以使用ENV或ARG設定RUN使用的變數,如果同名則ENV定義的值會覆蓋ARG定義的值,與ENV不同,ARG的變數值在編譯過程中是可變的,會對比使用編譯快取造成影響(ARG值不同則編譯過程也不同)
例子:ARG CONT_IMAG_VER <換行> RUN echo $CONT_IMG_VER
ARG CONT_IMAG_VER <換行> RUN echo hello
當編譯時給ARG變數賦值hello,則兩個Dockerfile可以使用相同的中間映象,如果不為hello,則不能使用同一個中間映象
指令:ONBUILD
功能描述:設定自徑想的編譯鉤子指令
語法:ONBUILD [INSTRUCTION]
提示:從該映象生成子映象,在子映象的編譯過程中,首先會執行父映象中的ONBUILD指令,所有編譯指令都可以成為鉤子指令
指令:STOPSIGNAL
功能描述:設定容器退出時,Docker Daemon向容器傳送的訊號量
語法:STOPSIGNAL signal
提示:訊號量可以是數字或者訊號量的名字,如9或者SIGKILL
,訊號量的數字說明在Linux系統管理中有簡單介紹
補充:ONBUILD流程
編譯時,讀取所有ONBUILD映象並記錄下來,在當前編譯過程中不執行指令
生成映象時將所有ONBUILD指令記錄在映象的配置檔案OnBuild關鍵字中
子映象在執行FROM指令時會讀取基礎映象中的ONBUILD指令並順序執行,如果執行過程中失敗則編譯中斷;當所有ONBUILD執行成功後開始執行子映象中的指令
子映象不會繼承基礎映象中的ONBUILD指令
補充:CMD ENTRYPOINT和RUN的區別
RUN
指令是設定編譯映象時執行的指令碼和程式,映象編譯完成後,RUN
指令的生命週期結束
容器啟動時,可以通過CMD
和ENTRYPOINT
設定啟動項,其中CMD
叫做容器預設啟動命令,如果在docker run
命令末尾新增command
,則會替換映象中CMD
設定的啟動程式;ENRTYPOINT
叫做入口程式,不能被docker run
命令末尾的command
替換,而是將command
當作字串,傳遞給ENTRYPOINT
作為引數
FROM ubuntu
ENTRYPOINT ["ps"]
//通過命令docker run --rm test啟動容器,列印ps的輸出
//通過命令docker run --rm test -ef啟動容器,列印ps -ef的輸出
在docker run
中,可以通過–entrypoin
t替換映象中的入口程式,在Dockerfile
中,應該至少有一條CMD
或者ENTRYPOINT
指令,如果同時定義了CMD
和ENTRYPOINT
則CMD
會作為引數傳遞給ENTRYPOINT
FROM ubuntu
ENTRYPOINT ["ps"]
CMD ["-ef"]
//通過命令docker run --rm test啟動容器,列印ps -ef的輸出
相關文章
- [Docker 系列]docker 學習七,DockerFile 編寫和實戰Docker
- 【Docker 系列】docker 學習七,DockerFile 編寫和實戰Docker
- Docker | dockerfile 檔案編寫Docker
- 實戰docker,編寫Dockerfile定製tomcat映象,實現web應用線上部署DockerTomcatWeb
- Docker的基本使用及DockerFile的編寫Docker
- 如何編寫 Dockerfile 檔案建立 Docker 映象Docker
- Dockerfile編寫Docker
- 編寫DockerFileDocker
- 如何編寫DockerfileDocker
- 小丸子學Docker系列之——實戰DockerfileDocker
- [Docker]寫 Dockerfile 的最佳實踐理論Docker
- 【Docker】動手寫Dockerfile學習DockerDocker
- IDEA的Docker外掛實戰(Dockerfile篇)IdeaDocker
- 學習編寫DockerfileDocker
- Docker小白到實戰之Dockerfile解析及實戰演示,果然順手Docker
- 如何編寫最佳的DockerfileDocker
- docker之Dockerfile實踐Docker
- [Docker 系列]docker 學習十,Compose 編寫規則及wp 實戰Docker
- 如何編寫優雅的DockerfileDocker
- Docker DockerfileDocker
- 快速編寫Dockerfile----php環境DockerPHP
- 高效編寫Dockerfile的幾條準則Docker
- 小白學Docker(九) Docker DockerfileDocker
- 靶場專案編寫實戰
- vue實戰-元件編寫-todolist元件Vue元件
- Vue 外掛編寫與實戰Vue
- 編寫dockerfile來部署laravel專案(待續)DockerLaravel
- Dockerfile指令與Docker-compose容器編排-搭建docker私有倉庫Docker
- Docker 入門:DockerfileDocker
- Docker_07 DockerfileDocker
- Docker的Dockerfile指令Docker
- Docker學習—DockerFileDocker
- Docker 基礎 : DockerfileDocker
- 實戰:dockerfile 最小實踐——koa 為例Docker
- 實戰:如何編寫一個 OpenTelemetry Extensions
- Prometheus之Dockerfile編寫、映象構建、容器啟動PrometheusDocker
- Docker實戰Docker
- Docker映象中提取DockerfileDocker