前面介紹了怎麼通過容器生成映象,這裡來記錄一下 DockerFile 構建映象,學習參考來自 菜鳥教程
系列文章歡迎訪問:https://www.itwxe.com/posts/9e76db89/
一、DockerFile是什麼
Dockerfile 是一個用來構建映象的文字檔案,文字內容包含了一條條構建映象所需的指令和說明。
-- 摘自菜鳥教程
說人話就是 Docker 提供了一系列的指令,Docker 引擎可以通過這些指令來構建出映象。
二、DockerFile指令
1 FORM
FORM 基礎映象
必須放在 DOckerfile 的第一行,表示從哪個 基礎映象 開始構建。
2 MAINTAINET
MAINTAINET 作者名稱
指定維護者的資訊。
3 COPY
COPY [--chown=<user>:<group>] <源路徑1>... <目標路徑>
COPY [--chown=<user>:<group>] ["<源路徑1>",... "<目標路徑>"]
[--chown=<user>:<group>]:可選引數,使用者改變複製到容器內檔案的擁有者和屬組
<目標路徑>:映象內的指定路徑,該路徑不用事先建好,路徑不存在的話,會自動建立
複製檔案到映象,例如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
和 ADD 不一樣的是源路徑不能訪問網路資源,也不會自動解壓壓縮包。
4 ADD
ADD 指令和 COPY 的使用格式一致(同樣需求下,官方推薦使用 COPY)。功能也類似,不同之處如下:
- ADD 的優點:在執行 <原始檔> 為 tar 壓縮檔案的話,壓縮格式為 gzip, bzip2 以及 xz 的情況下,會自動複製並解壓到 <目標路徑>,源路徑可以使用網路資源
- ADD 的缺點:在不解壓的前提下,無法複製 tar 壓縮檔案。會令映象構建快取失效,從而可能會令映象構建變得比較緩慢。具體是否使用,可以根據是否需要自動解壓來決定
5 RUN
shell 格式:
RUN <命令列命令>
# <命令列命令> 等同於,在終端操作的 shell 命令
exec 格式:
RUN ["可執行檔案", "引數1", "引數2"]
# RUN ["./test.sh", "param1", "param2"] 等價於 RUN ./test.sh param1 param2
構建映象時執行的命令,RUN用於在映象容器中執行命令
RUN指令建立的中間映象會被快取,並會在下次構建中使用。如果不想使用這些快取映象,可以在構建時指定 --no-cache
引數,如:docker build --no-cache
。
同時為了使構建出來的映象的檔案層數儘量小,shell 命令最好一次執行多條,使用 &&
連線,例如:mkdir data && cd data
。
6 CMD
CMD <shell 命令>
CMD ["<可執行檔案或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 該寫法是為 ENTRYPOINT 指令指定的程式提供預設引數
類似於 RUN 指令,但是 CMD 是容器啟動時執行的命令,並且定義多個 CMD 命令的時候,僅最後一個會生效。
菜鳥教程中指出,推薦使用第二種,第一種格式實際上在執行的過程中也會自動轉換成第二種格式執行,並且預設可執行檔案是 sh。
7 ENTRYPOINT
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
類似於 CMD 指令,但其不會被 docker run 的命令列引數指定的指令所覆蓋,而且這些命令列引數會被當作引數送給 ENTRYPOINT 指令指定的程式。
但是, 如果執行 docker run 時使用了 --entrypoint
選項,將覆蓋 CMD 指令指定的程式。
在執行 docker run 的時候可以指定 ENTRYPOINT 執行所需的引數。
和 CMD 類似,如果 Dockerfile 中如果存在多個 ENTRYPOINT 指令,僅最後一個生效。
可以搭配 CMD 命令使用:一般是變參才會使用 CMD ,這裡的 CMD 等於是在給 ENTRYPOINT 傳參。
示例:
假設已通過 Dockerfile 構建了 nginx:test 映象:
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定參
CMD ["/etc/nginx/nginx.conf"] # 變參
1、不傳參執行。
docker run nginx:test
容器內會預設執行以下命令,啟動主程式。
nginx -c /etc/nginx/nginx.conf
2、傳參執行。
docker run nginx:test -c /etc/nginx/new.conf
容器內會預設執行以下命令,啟動主程式(/etc/nginx/new.conf:假設容器內已有此檔案)。
nginx -c /etc/nginx/new.conf
8 EXPOSE
EXPOSE <埠1> [<埠2>...]
告訴Docker服務端暴露埠,在容器啟動時需要通過 -p 做埠對映。
9 EVN
ENV <key>=<value>
設定環境變數,定義了環境變數,那麼在後續的指令中,就可以使用這個環境變數。
10 WORKDIR
WORKDIR <工作目錄路徑>
指定工作目錄。用 WORKDIR 指定的工作目錄,會在構建映象的每一層中都存在。
WORKDIR 指定的工作目錄,必須是提前建立好的。
11 USER
USER <使用者名稱>[:<使用者組>]
用於指定執行後續命令的使用者和使用者組,這邊只是切換後續命令執行的使用者(使用者和使用者組必須提前已經存在)。
12 VOLUME
VOLUME ["<路徑1>", "<路徑2>"...]
VOLUME <路徑>
定義匿名資料卷。在啟動容器時忘記掛載資料卷,會自動掛載到匿名卷,通常用於 MySQL 等儲存需要持久化資料,啟動容器時也可以通過 -v 掛載。
三、演示例子
1、建立目錄,下載好編譯好的 jdk 檔案上傳,專案 jar 包上傳。
mkdir /itwxe/DockerFile && cd /itwxe/DockerFile
2、建立 Dockerfile 檔案,名字必須叫 Dockerfile,新增內容。
vim Dockerfile
# 新增內容,為了儘量多使用點指令,基於 centos 映象來演示,當然如果為了執行 jar 當然首選 openjdk 為基礎映象
# 基礎映象是 centos
FROM centos
# 維護者 tudouge
MAINTAINER itwxe
# 複製JDK
COPY jdk1.8.0_202 jdk1.8.0_202
# 將專案的新增到映象中
COPY sunny-admin.jar docker-sunny.jar
# 配置jdk環境
ENV JAVA_HOME=/jdk1.8.0_202
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
# 容器對外提供服務的埠是 9002
EXPOSE 9002
# 啟動容器後啟動app.jar的應用
ENTRYPOINT ["java","-jar","docker-sunny.jar"]
3、注意目錄結構
4、編譯並生成映象
其中 .
代表上下文路徑,該目錄下的檔案都會打包進映象,我們的 jdk 和 jar 包就是都放在這個目錄下,當需要 COPY 等操作時都是從這個目錄下查詢。
docker build -t tudouge/sunny-admin .
打包過程如下,可以看到映象建立成功。
5、建立容器執行看下,專案是否正常。
docker run -d --name sunny -p 9002:9002 itwxe/sunny-admin
可以看到專案正常執行,這是我自己寫的一個基礎應用框架,該有的基礎都有了,就差業務開發了,以後準備寫一個系列搭建教程,找個好一點的方向。
至此就成功通過 Dockerfile 建立映象並執行了,但是這種方式過於麻煩,需要上傳 jar 包到 Docker 環境,而作為一個 Java 程式設計師,當然不想使用這麼麻煩的打包方式,下一篇開始通過 maven 外掛一鍵打包 SpringBoot 映象併發布到伺服器。
都讀到這裡了,來個 點贊、評論、關注、收藏 吧!
文章作者:IT王小二
首發地址:https://www.itwxe.com/posts/be6627e1/
版權宣告:文章內容遵循 署名-非商業性使用-禁止演繹 4.0 國際 進行許可,除特殊宣告外皆為原創,轉載請在文章頁面明顯位置給出作者與原文連結。