DockerFile構建映象

IT王小二發表於2021-07-14

前面介紹了怎麼通過容器生成映象,這裡來記錄一下 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、注意目錄結構

DockerFile目錄結構

4、編譯並生成映象

其中 . 代表上下文路徑,該目錄下的檔案都會打包進映象,我們的 jdk 和 jar 包就是都放在這個目錄下,當需要 COPY 等操作時都是從這個目錄下查詢。

docker build -t tudouge/sunny-admin .

打包過程如下,可以看到映象建立成功。

編譯並生成映象

5、建立容器執行看下,專案是否正常。

docker run -d --name sunny -p 9002:9002 itwxe/sunny-admin

dockerfile專案執行結果

可以看到專案正常執行,這是我自己寫的一個基礎應用框架,該有的基礎都有了,就差業務開發了,以後準備寫一個系列搭建教程,找個好一點的方向。

至此就成功通過 Dockerfile 建立映象並執行了,但是這種方式過於麻煩,需要上傳 jar 包到 Docker 環境,而作為一個 Java 程式設計師,當然不想使用這麼麻煩的打包方式,下一篇開始通過 maven 外掛一鍵打包 SpringBoot 映象併發布到伺服器。

都讀到這裡了,來個 點贊、評論、關注、收藏 吧!

文章作者:IT王小二
首發地址:https://www.itwxe.com/posts/be6627e1/
版權宣告:文章內容遵循 署名-非商業性使用-禁止演繹 4.0 國際 進行許可,除特殊宣告外皆為原創,轉載請在文章頁面明顯位置給出作者與原文連結。

相關文章