Dockerfile:Docker中構建鏡像用到的文本文檔
在我們進行JavaEE開發的時候,經常使用Maven或者Gradle進行包管理,當我們需要某一個包時,只需在Maven或者Gradle添加該包的唯一標識,這個包就能從遠程倉庫拉取到本地,搭建私服的也會先從私服里拉取該包。當我們自己封裝了一個比較好的包,也可以通過這些工具推送給遠程倉庫。正好,Docker鏡像的拉取或者推送也是相同的原理。
通過前兩章的講解,相信大家對于Docker的相關概念、常用命令有了基本的了解,也知道怎么從遠程 Pull 一個鏡像,那遠程的鏡像是怎么來的呢?如果我們想自己創建一個鏡像又該怎么做呢?今天就來說一說Dockerfile!Dockerfile 是一個包含用戶能夠構建鏡像的所有命令的文本文檔,它有自己的語法以及命令,Docker 能夠從 Dockerfile 中讀取指令自動的構建鏡像!
Dockerfiler的本質是一個文本文檔,既然是一個文本文檔,就要了解這個文檔的編寫規則,也就是對 Dockerfile 的語法和命令需要了解,下面就來說一說它的相關指令!
1、FROM
- 語法:
- FROM <image> [AS<name>]
- FROM <image>[:<tag>][AS <name>]
- FROM<image>[@<digest>] [AS <name>]
from就是從哪里來,對于Docker官方說法就是指定基礎鏡像,當前鏡像是基于哪個鏡像創建的,有點類似 Java 中的類繼承。FROM 指令必是 Dockerfile 文件中的首條命令。
2、MAINTAINER
- 語法:
- MAINTAINER <name>
鏡像維護者的信息,已經舍棄該指令。
3、LABEL
- 語法:
- LABEL<key>=<value><key>=<value><key>=<value> ...
4、ENV
ENV
設置環境變量!
5、WORKDIR
- WORKDIR /path/to/workdir
設置工作目錄,在該指令后的 RUN、CMD、ENTRYPOINT, COPY、ADD 指令都會在該目錄執行。如果該目錄不存在,則會創建!
6、RUN
- RUN <command>
- RUN ["executable","param1", "param2"]
RUN 會在當前鏡像的最上面創建一個新層,并且能執行任何的命令,然后對執行的結果進行提交。提交后的結果鏡像在 Dockerfile 的后續步驟中可以使用。
7、ADD
- ADD[--chown=<user>:<group>] <src>... <dest>
- ADD[--chown=<user>:<group>] ["<src>",..."<dest>"]
從宿主機拷貝文件或者文件夾到鏡像,也可以復制一個網絡文件!如果拷貝的文件是一個壓縮包,會自動解壓縮!
8.COPY
- COPY[--chown=<user>:<group>] <src>... <dest>
- COPY[--chown=<user>:<group>] ["<src>",..."<dest>"]
從宿主機拷貝文件或者文件夾到鏡像,不能復制網絡文件也不會自動解壓縮!
9、VOLUME
- VOLUME ["/data"]
VOLUME 用于創建掛載點,一般配合 run 命令的 -v 參數使用。
10、EXPOSE
- EXPOSE <port>[<port>/<protocol>...]
指定容器運行時對外暴露的端口,但是該指定實際上不會發布該端口,它的功能是鏡像構建者和容器運行者之間的記錄文件。
回到容器命令中的 run 命令部分,run 命令有 -p 和 -P 兩個參數。
如果是 -P 就是隨機端口映射,容器內會隨機映射到 EXPOSE 指定的端口;如果是 -p 就是指定端口映射,告訴運維人員容器內需要映射的端口號。
11、CMD
- CMD["executable","param1","param2"]
- CMD["param1","param2"]
- CMD command param1 param2
指定容器啟動時默認運行的命令,在一個 Dockerfile 文件中,如果有多個 CMD 命令,只有一個最后一個會生效!
12、ENTRYPOINT
- ENTRYPOINT["executable", "param1", "param2"]
- ENTRYPOINT command param1 param2
這個指令與 CMD 指令類似,都是指定啟動容器時要運行的命令,如果指定了 ENTRYPOINT,則 CMD 指定的命令不會執行!
在一個 Dockerfile 文件中,如果有多個 ENTRYPOINT 命令,也只有一個最后一個會生效!不同的是通過 docker run command 命令會覆蓋 CMD 的命令!
執行的命令不會覆蓋 ENTRYPOINT,docker run 命令中指定的任何參數都會被當做參數傳遞給 ENTRYPOINT!
RUN、CMD、ENTRYPOINT 區別:
---RUN 指令是在鏡像構建時運行,而后兩個是在容器啟動時執行!
---CMD 指令設置的命令是容器啟動時默認運行的命令,如果 docker run 沒有指定任何的命令,并且 Dockerfile 中沒有指定 ENTRYPOINT,那容器啟動的時候就會執行 CMD 指定的命令!有點類似代碼中的缺省參數!
---如果設置了 ENTRYPOINT 指令,則優先使用!并且可以通過 dockerrun 給該指令設置的命令傳參!
---CMD 有點類似代碼中的缺省參數。
13、USER
- USER <user>[:<group>]
- USER <UID>[:<GID>]
用于指定運行鏡像所使用的用戶。
14、ARG
- ARG <name>[=<defaultvalue>]
指定在鏡像構建時可傳遞的變量,定義的變量可以通過 dockerbuild --build-arg = 的方式在構建時設置。
15、ONBUILD
- ONBUILD [INSTRUCTION]
當所構建的鏡像被當做其他鏡像的基礎鏡像時,ONBUILD 指定的命令會被觸發!
16、STOPSIGNAL
- STOPSIGNAL signal
設置當容器停止時所要發送的系統調用信號!
17、HEALTHCHECK
- HEALTHCHECK [OPTIONS] CMD command (在容器內運行運行命令檢測容器的運行情況)
- HEALTHCHECK NONE (禁止從父鏡像繼承檢查)
該指令可以告訴 Docker 怎么去檢測一個容器的運行狀況!
18、SHELL
- SHELL ["executable","parameters"]
用于設置執行命令所使用的默認的 Shell 類型!該指令在 Windows 操作系統下比較有用,因為 Windows 下通常會有 CMD 和 Powershell 兩種 Shell,甚至還有 SH。
以上就是Dockerfile的相關指令,既然對這些指令有了大概的了解,那么怎么來構建呢?當然使用Docker提供的構建命令:docker build [OPTIONS] PATH | URL | -
-f:指定要使用的 Dockerfile 路徑,如果不指定,則在當前工作目錄尋找 Dockerfile 文件!
-t:鏡像的名字及標簽,通常 name:tag 或者 name 格式;可以在一次構建中為一個鏡像設置多個標簽。
看看redis和nodejs的Dockerfile長什么樣:

