一 Dockerfile介紹
Dockerfile是一種被Docker程序解釋執行的腳本,由一條條的命令組成,每條命令對應linux下面的一條命令,Docker程序將這些Dockerfile指令在翻譯成真正的linux命令,其有自己的書寫方式和支持的命令,Docker程序讀取Dockerfile並根據指令生成Docker鏡像,相比手動制作鏡像的方式,Dockerfile更能直觀的展示鏡像時怎么產生的,有了Dockerfile,當后期有額外的需求時,只要在之前的Dockerfile添加或者修改相應的命令即可重新生成新的docker鏡像,避免了重復手動制作鏡像。
Docker守護程序Dockerfile逐一運行指令。
二 Dockerfile制作流程
三 Dockerfile文件格式
3.1 Dockerfile文件說明
- 每一行以Dockerfile的指令開頭,指令不區分大小寫,但是慣例使用大寫
- 使用#開始作為注釋
- 每一行只支持一條指令,每條指令可以攜帶多個參數
- 指令按文件的順序從上至下進行執行
- 每個指令的執行會生成一個新的鏡像層,為了減少分層和鏡像大小,僅可能將多條指令合並成一條指令
- 制作鏡像一般可能需要反復多次,每次執行Dockerfile都按順序執行,從頭開始,已經執行過的指令已經緩存,不需要在執行,如果后續有一行新的執行沒有執行過,其往后的執行將會重新執行,所以為加速鏡像制作,將最常變化的內容放在Dockerfile的文件后面
3.2 Dockerfile相關指令
- FROM:就是指定基礎鏡像,此指令通常必須放在Dockerfile文件第一個非注釋行,后續的指令都是運行於此基准鏡像所提供的運行環境
- LABEL:指定鏡像元數據,如鏡像作者等
- MAINTAINER:指定維護者信息,此指令已過時,用LABEL替代
- RUN:用來在構建鏡像階段需要執行FROM指定鏡像所支持的shell命令
- shell格式
- RUN <命令>
- exec格式
- RUN ["/bin/bash","-c","ls"]
- shell格式
- ENV:設置環境變量,會被后續指令通過$KEY或${KEY}進行引用,並在容器運行時保持
- COPY:復制本地宿主機的文件到容器內
- ADD:該命令可認為是增強版的COPY,不僅支持COPY,還支持自動伸縮。可以將復制指定的文件到容器內
- 可以是Dockerfile所在目錄的一個相對路徑,也可以是一個URL,還可以是一個tar文件會自動解壓
- 可以是絕對路徑或者是WORKDIR指定的相對路徑
- 如果是目錄,只復制目錄中的內容,而非目錄本身
- 如果是一個URL,下載后的文件權限自動設置為600
- 如果為URL且不以/結尾,則指定的文件將被下載並直接被創建,如果以/結尾,則文件名URL指定的文件將被直接下載並保存為/<filename>
- 如果是本地文件系統上的打包文件,如:gz,bz2,xz,它將被解壓,但是通過URL獲取到的tar文件將不會自動展開
- 如果有多個或其間接使用了通配符,則必須是一個以/結尾的目錄路徑,如果不以/結尾,則其被視作一個普通文件
- CMD:啟動容器命令
- 如果docker run沒有指定任何的執行命令或者Dockerfile里也沒有ENTRYPOINT,那么啟動容器時就會執行CMD指定的默認命令
- 每個Dockerfile只能有一條CMD命令。如果指定了多條,只有最后一條被執行
- 如果用戶啟動容器時用docker run 指定運行命令,則會覆蓋CMD指定的命令
- ENTRYPOINT:功能類似於CMD,配置容器啟動后執行的命令及參數
- ENTRYPOINT不能被docker run提供的參數覆蓋,而是追加,即如果docker run命令有參數,那么參數全部都會作為ENTTRYPOINT的參數
- 如果docker run后面沒有額外參數,但是Dockerfile中的CMD里有,即Dockerfile中即有CMD也有ENTRYPOINT,那么CMD全部內容作為ENTRYPOINT的參數
- 如果docker run后面有額外的參數,同時Dockerfile中既有CMD也有ENTRYPOINT,那么docker run后面的參數覆蓋掉CMD參數內容,最終作為ENTRYPOINT的參數
- 可以通過docker run --entrypoint string參數在運行時替換注意string不要加空格
- 使用CMD要在運行時從新寫命令本身,然后在后面才能追加運行參數,ENTRYPOINT則可以運行時無需重寫命令就可以直接接收新參數
- 每個Dockerfile中只能有一個ENTRYPOINT,當指定多個時,只有最后一個生效
- ARG:構建參數,在build階段指定變量和ENV不同的是,容器運行時不會存在這些環境變量
- VOLUME:匿名卷
- 在容器創建一個可以從本地主機或其它容器掛載的掛載點,一般用來存放數據庫和需要保持的數據等,一般會將宿主機上的目錄掛載至VOLUME指令指定的容器目錄,即時容器后期刪除,此宿主機的目錄仍會保留,從而實現容器數據的持久保持
- EXPOSE:暴露端口,指定服務端的容器需要對外暴露的端口號,以實現容器與外部通信
- WORKDIE:指定工作目錄,為后續的RUN、CMD、ENTRYPOINT指定配置工作目錄,當容器運行后,進入容器內WORKDIR指定的默認目錄,當該目錄不存在時會自動創建
- ONBUILD:子鏡像引用父鏡像的指令,可以用來配置當構建鏡像的子鏡像時,會自動觸發執行的指令,但在當前鏡像構建時,並不會執行,即延遲到子鏡像構建時才執行
- USER:指定當前用戶,指定運行容器的用戶名或UID,后續的RUN也會指定用戶,需要指定的用戶名存在
- HEALTHCHECK:健康檢查
- STOPSIGNAL:退出容器的信號
- SHELL:指定shell
3.3 .dockerignore文件
與.gitignore文件類似,生成構建上下文時docker客戶端應忽略的文件和文件夾指定模式。
.dockerignore使用go的文件路徑規則filepath.Match
- # #以#開頭的行為注釋
- * #匹配任何非分隔符字符序列
- ? #匹配任何單個非分隔符
- \\ #表示 \
- ** #匹配任意數量的目錄,例如,**/**.go 將排除在所有目錄中以.go結尾的所有文件
- ! #表示取反,可用於排除例外情況
四 docker build命令
4.1 docker build命令使用幫助
~# docker build -h
Flag shorthand -h has been deprecated, please use --help
Usage: docker build [OPTIONS] PATH | URL | -
Options:
--Add -host list #添加一個自定義主機到ip的映射(host:ip)
--build-arg list #設置構建時變量
--cache-from strings #圖像作為緩存源
--cgroup-parent string #容器的可選父cgroup
--compress #使用gzip壓縮構建上下文
--CPU -period int #限制CPU的CFS(完全公平調度)周期
--CPU -quota int #限制CPU CFS(完全公平調度)配額
-c,--CPU -shares int #CPU份額(相對權重)
--cpu -cpu string #允許執行的cpu (0-3, 0,1)
--cpuset-mems string #允許執行的MEMs (0- 3,0,1)
--disable-content-trust #跳過圖像驗證(默認為true)
-f,--file string # Dockerfile的名稱(默認為'PATH/Dockerfile')
--force-rm #始終刪除中間容器
--iidfile string #將圖像ID寫入文件
--isolation string #容器隔離技術
--label list #設置圖像的元數據
-m,--內存字節#內存限制
--memory-swap bytes #交換限制等於內存加上交換:'-1'表示啟用無限交換
--network string #在構建過程中設置RUN指令的網絡模式(默認為“default”)
--no-cache #在構建映像時不要使用緩存
--pull #總是嘗試拖動圖像的新版本
-q,--quiet #在成功時禁止構建輸出和打印映像ID
--rm #在成功構建后刪除中間容器(默認為true)
--Security -opt strings #安全選項
--shm-size bytes # /dev/shm的大小
-t,--tag list #名稱和一個可選的' Name:tag'格式的標簽
--target string #設置目標構建階段為構建。
--ulimit ulimit # ulimit選項(默認[])
4.2 使用示例
docker build . docker build -f /path/to/a/Dockerfile . docker build -t shykes/myapp . docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .