docker build 命令原理
- docker build 命令從 Dockerfile 和上下文構建鏡像
- 構建的上下文:位於指定 PATH 或 URL 中的一組文件
- 構建過程可以引用上下文中的任何文件,例如,構建可以使用 COPY 指令來引用上下文中的文件
- PATH:就是本地文件系統上的一個目錄路徑
- URL:Git 地址
- 個人理解:以設置的上下文為根目錄,在 dockerfile 中寫的文件路徑都會以這個上下文開始找
構建上下文是遞歸處理的
PATH 包含任何子目錄,URL 包含 repository 及其子模塊
簡單的栗子
上下文為當前目錄
也是最簡單的 docker build 使用方式
docker build .
- 指定 PATH 為 . ,因此本地目錄中的所有文件都會被延遲並發送到 Docker 守護程序
- PATH 指定在哪里可以找到 Docker 守護程序上構建的“上下文”的文件
- 請記住,守護進程可以在遠程機器上運行,並且不會在客戶端(運行 docker build 的地方)解析 Dockerfile
- 這意味着 PATH 中的所有文件都會被發送,而不僅僅是 Dockerfile 中列出的 ADD 文件
- 當看到 Sending build context 消息時,docker 客戶端的意思是將上下文從本地機器傳輸到 Docker 守護進程。
構建由 Docker 守護程序(Daemon)運行
- 而不是 CLI(命令行)運行
- 構建過程做的第一件事是將整個上下文(遞歸)發送到守護進程
- 官方建議:將一個空目錄作為上下文起點,並將 Dockerfile 保存在該目錄中,僅添加構建 Dockerfile 所需的文件
特別注意
不要使用根目錄 / 作為構建上下文的 PATH,因為會導致構建時,將硬盤驅動器的全部內容發送到 Docker 守護程序
逐一運行
- Docker 守護進程將逐一運行 Dockerfile 中的指令,如有必要,會將每條指令的結果提交到新鏡像,最后會輸出一個最新鏡像的 ID
- Docker 守護進程將自動清理發送的上下文
- 重點:每條指令都是獨立運行的,並會創建一個新鏡像,因此像 RUN cd /tmp 不會對下一條自定產生任何影響
- 只要有可能,Docker 就會使用構建緩存來加速 Docker 構建過程,這由控制台輸出中的 CACHED 消息指示
> docker build -t svendowideit/ambassador . [internal] load build definition from Dockerfile 0.1s => transferring dockerfile: 286B 0.0s [internal] load .dockerignore 0.1s => transferring context: 2B 0.0s [internal] load metadata for docker.io/library/alpine:3.2 0.4s CACHED [1/2] FROM docker.io/library/alpine:3.2@sha256:e9a2035f9d0d7ce 0.0s CACHED [2/2] RUN apk add --no-cache socat 0.0s exporting to image 0.0s => exporting layers 0.0s => writing image sha256:1affb80ca37018ac12067fa2af38cc5bcc2a8f09963de 0.0s => naming to docker.io/svendowideit/ambassador 0.0s
命令行參數
-f,--file
指定 dockerfile 路徑
docker build -f /path/to/a/Dockerfile .
不指定的話,默認會讀取上下文路徑( . )下的 dockerfile
-t,--tag
指定構建的鏡像名和 tag
docker build -t ubuntu-nginx:v1 .
構建的鏡像指定多個 tag
docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
--add-host
可以使用一個或多個 --add-host 標志將其他主機添加到容器的 /etc/hosts 文件中
docker build --add-host=docker:10.180.0.1 .
--no-cache
構建鏡像時不使用緩存
--network
在構建過程中為 RUN 指令設置網絡模式
更多參數可以看官方文檔
https://docs.docker.com/engine/reference/commandline/build/