本文基於應用容器引擎-Docker繼續講解DockerFile的有關知識。在學習完Dockerfile的知識後,你可以自己獨立部署一個前後端分離的專案,具體部署操作可以瀏覽我之前的部落格:部署實戰-Docker+nginx部署前後端分離專案
@Author:Akai-yuan
@更新時間:2023/2/2
Dockerfile 是一個用來構建映象的文字檔案
我們直接從倉庫獲取的映象可能很多時候是不滿足我們的需求,比如你有這個需求場景:部署你的SpringBoot專案:
1.基於JDK1.8的映象
2.需要將自己的jar等檔案放到映象目錄
3.執行映象後需要啟動SpringBoot專案
這時候如果直接從倉庫獲取映象,然後執行成容器,並進入容器部署自己的專案,這一列操作就非常麻煩。
而如果有的Dockerfile,則可以一次性生成滿足你需求的自有映象。
以下範例將展示:如何構建一個基於JDK1.8的SpringBoot專案
例如:/usr/local/dockerfile
在上面的目錄下建立一個Dockerfile檔案,檔名最好使用Dockerfile,這樣生成映象的命令就不用指定檔案了,檔案內容如下:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
COPY *.jar demo.jar
ENTRYPOINT ["java","-jar","/demo.jar"]
可以使用Idea連線遠端伺服器,也可以通過Xftp上傳,或者在Xshell中執行rz指令
關於linux中的rz命令:
rz [選項]
選項說明:
-+, --append:將檔案內容追加到已存在的同名檔案
-a,--ascii:以文字方式傳輸
-b, --binary:以二進位制方式傳輸,推薦使用
--delay-startup N:等待N秒
-e, --escape:對所有控制字元跳脫,建議使用
-E, --rename:已存在同名檔案則重新命名新上傳的檔案,以點和數位作為字尾
-p, --protect:對ZMODEM協定有效,如果目標檔案已存在則跳過 -
-q, --quiet:安靜執行,不輸出提示資訊
-v, --verbose:輸出傳輸過程中的提示資訊
-y, --overwrite:存在同名檔案則替換
-X, --xmodem:使用XMODEM協定
--ymodem:使用YMODEM協定
-Z, --zmodem:使用ZMODEM協定
--version:顯示版本資訊
--h, --help:顯示幫助資訊
但是其實博主在使用rz命令從使用者端上傳檔案到伺服器端時,經常會遇到上傳異常中斷,然後生成亂碼檔案,此時還需要rm -rf 檔名清除掉指定檔案。所以其實能用Xftp的話還是儘量避免使用rz。
docker build -t 映象名稱:標籤名 .
docker build -t demo:v1 .
生成完成之後,檢視本地映象:
docker ps
以上就是一個簡單的Dockerfile構建映象的範例
FROM命令是Dockerfile檔案的開始,標識建立的映象是基於哪個映象
格式:FROM 映象名[:標籤名]
FROM 映象名[:標籤名]
# 範例1:基於Nginx
FROM nginx
# 範例2:基於openjdk:8-jdk-alpine
FROM openjdk:8-jdk-alpine
複製指令,從上下文目錄中複製檔案或者目錄到容器裡指定路徑
格式:
COPY [--chown=:] <源路徑1>... <目標路徑>
COPY [--chown=:] ["<源路徑1>",... "<目標路徑>"]
# 將以hom開頭的檔案和目錄拷貝到容器目錄下
COPY hom* /mydir/
# 將一些檔案拷貝到容器目錄下
COPY hom?.txt /mydir/
# 將一個檔案拷貝到容器,並重新命名
COPY xxxx.jar abc.jar
ADD 指令和 COPY 的使用格類似(同樣需求下,官方推薦使用 COPY)。功能也類似,不同之處如下:
ADD 的優點:
在執行 <原始檔> 為 tar 壓縮檔案的話,壓縮格式為 gzip, bzip2 以及 xz 的情況下,會自動複製並解壓到 <目標路徑>。
ADD 的缺點:
在不解壓的前提下,無法複製 tar 壓縮檔案。會令映象構建快取失效,從而可能會令映象構建變得比較緩慢。具體是否使用,可以根據是否需要自動解壓來決定。
用於執行後面跟著的命令列命令。
注意:RUN是在docker build時執行,而非docker run時執行
Shell格式:
RUN <shell 命令>
# 範例一
FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
# 範例二,合併簡化
FROM centos
RUN yum -y install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
exec格式:
RUN ["可執行檔案", "引數1", "引數2"]
# 等價於 RUN ./test.php dev offline
RUN ["./test.php", "dev", "offline"]
類似於 RUN 指令,用於執行程式。與RUN不同的是,CMD命令是在docker run時執行
格式:
CMD <shell 命令>
CMD ["<可執行檔案或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 該寫法是為 ENTRYPOINT 指令指定的程式提供預設引數
推薦使用第二種格式,執行過程比較明確。第一種格式實際上在執行的過程中也會自動轉換成第二種格式執行,並且預設可執行檔案是 sh。
範例:
# CMD <shell 命令>
CMD java -jar demo.jar
# CMD ["<可執行檔案或命令>","<param1>","<param2>",...]
CMD ["java","-jar","demo.jar"]
# CMD ["<param1>","<param2>",...] 為 ENTRYPOINT 指令指定的程式提供預設引數
CMD ["/etc/nginx/nginx.conf"]
6.ENTRYPOINT
類似於 CMD 指令,但其不會被 docker run 的命令列引數指定的指令所覆蓋,而且這些命令列引數會被當作引數送給 ENTRYPOINT 指令指定的程式。
但是, 如果執行 docker run 時使用了 --entrypoint 選項,將覆蓋 ENTRYPOINT 指令指定的程式。
優點:在執行 docker run 的時候可以指定 ENTRYPOINT 執行所需的引數。
注意:如果 Dockerfile 中如果存在多個 ENTRYPOINT 指令,僅最後一個生效。
格式:
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
可以搭配 CMD 命令使用:一般是變參才會使用 CMD ,這裡的 CMD 等於是在給 ENTRYPOINT 傳參,見以下範例。
範例:
假設已通過 Dockerfile 構建了 nginx:test 映象:
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 可以在docker run -c 指定引數
CMD ["/etc/nginx/nginx.conf"] # 給ENTRYPOINT約定預設引數
不傳參執行:
docker run nginx:test
# 相當於nginx -c /etc/nginx/nginx.conf
傳參執行:
docker run nginx:test -c /etc/nginx/new.conf
# 忽略CMD中的引數,使用自定義引數
7.ENV
設定環境變數,定義了環境變數,那麼在後續的指令中,就可以使用這個環境變數
格式:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
以下範例設定 NODE_VERSION = 7.2.0 , 在後續的指令中可以通過 $NODE_VERSION 參照:
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
8.ARG
構建引數,與 ENV 作用一致。不過作用域不一樣。ARG 設定的環境變數僅對 Dockerfile 內有效,也就是說只有 docker build 的過程中有效,構建好的映象內不存在此環境變數。
構建命令 docker build 中可以用 --build-arg <引數名>=<值> 來覆蓋。
格式:
ARG <引數名>[=<預設值>]
9.VOLUME
定義匿名資料卷。在啟動容器時忘記掛載資料卷,會自動掛載到匿名卷。
作用:
避免重要的資料,因容器重啟而丟失,這是非常致命的。
避免容器不斷變大。
格式:
VOLUME ["<路徑1>", "<路徑2>"...]
VOLUME <路徑>
在啟動容器 docker run 的時候,我們可以通過 -v 引數修改掛載點。
僅僅只是宣告埠。
作用:
幫助映象使用者理解這個映象服務的守護埠,以方便設定對映。
在執行時使用隨機埠對映時,也就是 docker run -P 時,會自動隨機對映 EXPOSE 的埠。
格式:
EXPOSE <埠1> [<埠2>...]
11.WORKDIR
指定工作目錄。用 WORKDIR 指定的工作目錄,會在構建映象的每一層中都存在。(WORKDIR 指定的工作目錄,必須是提前建立好的)。
docker build 構建映象過程中的,每一個 RUN 命令都是新建的一層。只有通過 WORKDIR 建立的目錄才會一直存在。
格式:
WORKDIR <工作目錄路徑>
12.USER
用於指定執行後續命令的使用者和使用者組,這邊只是切換後續命令執行的使用者(使用者和使用者組必須提前已經存在)。
格式:
USER <使用者名稱>[:<使用者組>]
用於指定某個程式或者指令來監控 docker 容器服務的執行狀態。
格式:
HEALTHCHECK [選項] CMD <命令>:設定檢查容器健康狀況的命令
HEALTHCHECK NONE:如果基礎映象有健康檢查指令,使用這行可以遮蔽掉其健康檢查指令
14.ONBUILD
用於延遲構建命令的執行。簡單的說,就是 Dockerfile 裡用 ONBUILD 指定的命令,在本次構建映象的過程中不會執行(假設映象為 test-build)。當有新的 Dockerfile 使用了之前構建的映象 FROM test-build ,這時執行新映象的 Dockerfile 構建時候,會執行 test-build 的 Dockerfile 裡的 ONBUILD 指定的命令。
格式:
ONBUILD <其它指令>
LABEL 指令用來給映象新增一些後設資料(metadata),以鍵值對的形式,語法格式如下:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
比如我們可以新增映象的作者:
LABEL org.opencontainers.image.authors="runoob"
# 格式
docker build [OPTIONS] PATH | URL | -
# 範例
docker build -t 映象名:標籤名 .
引數說明:
–build-arg=[] :設定映象建立時的變數;
–cpu-shares :設定 cpu 使用權重;
–cpu-period :限制 CPU CFS週期;
–cpu-quota :限制 CPU CFS配額;
–cpuset-cpus :指定使用的CPU id;
–cpuset-mems :指定使用的記憶體 id;
–disable-content-trust :忽略校驗,預設開啟;
-f :指定要使用的Dockerfile路徑;
–force-rm :設定映象過程中刪除中間容器;
–isolation :使用容器隔離技術;
–label=[] :設定映象使用的後設資料;
-m :設定記憶體最大值;
–memory-swap :設定Swap的最大值為記憶體+swap,"-1"表示不限swap;
–no-cache :建立映象的過程不使用快取;
–pull :嘗試去更新映象的新版本;
–quiet, -q :安靜模式,成功後只輸出映象 ID;
–rm :設定映象成功後刪除中間容器;
–shm-size :設定/dev/shm的大小,預設值是64M;
–ulimit :Ulimit設定。
–squash :將 Dockerfile 中所有的操作壓縮為一層。
-t: 映象的名字及標籤,通常 name:tag 或者 name 格式;可以在一次構建中為一個映象設定多個標籤。
–network: 預設 default。在構建期間設定RUN指令的網路模式