Docker利用Dockerfile與docker?build命令構(gòu)建鏡像指南
一、鏡像制作簡介
Docker鏡像能將應用程序及其所有依賴(如庫、配置、運行時環(huán)境等)打包成一個標準化的、可移植的文件,確保應用在任何支持Docker的環(huán)境中都能以相同方式運行,從而解決"在我這能跑,到你那卻不行"的環(huán)境一致性問題,同時簡化部署流程、提高擴展效率,并通過容器化實現(xiàn)資源隔離與輕量化管理,讓應用的開發(fā)、測試和生產(chǎn)環(huán)境保持統(tǒng)一,大幅降低跨環(huán)境部署的復雜度和出錯概率。
制作鏡像主要有兩種方式:
- 使用
docker commit指令:基于運行中的容器手動創(chuàng)建鏡像,這種方式操作簡單但缺乏可重復性,鏡像構(gòu)建過程難以追溯和維護,不推薦用于生產(chǎn)環(huán)境。 - 使用Dockerfile文件:通過編寫結(jié)構(gòu)化的文本文件定義鏡像構(gòu)建步驟,支持版本控制、自動化構(gòu)建和精確配置,能清晰記錄鏡像制作過程,便于團隊協(xié)作與迭代優(yōu)化,是推薦的標準做法。
相比docker commit,使用 Dockerfile 構(gòu)建鏡像是絕對的主流做法,核心優(yōu)勢如下:
1. 自動化 & 可重復
- 文本文件定義流程,
docker build一鍵生成。 - 環(huán)境、配置、步驟完全一致,杜絕“在我這好使”的問題。
2. 透明 & 可追溯
- 所有構(gòu)建步驟(裝了啥、改了啥)一目了然。
- 文件可存入 Git,誰改了哪里,歷史可查。
3. 高效 & 快速
利用分層緩存:只重建變更的步驟,大幅提升構(gòu)建速度。
4. 易維護 & 最佳實踐
- 輕松實施優(yōu)化(如用小體積基礎(chǔ)鏡像、合并指令)。
- 結(jié)構(gòu)清晰,易于理解和修改。
5. 天生適合 CI/CD
完美集成自動化流程,實現(xiàn)代碼提交后自動構(gòu)建、測試、部署。
二、Dockerfile文件配置
Dockerfile 就是鏡像的藍圖,Dockerfile與鏡像的關(guān)系如同圖紙與房子的關(guān)系

Dockerfile格式:
# Comment INSTRUCTION arguments
2.1 常用命令清單
官方地址:https://docs.docker.com/reference/dockerfile/
FROM:構(gòu)建鏡像基于哪個鏡像,也就是基礎(chǔ)鏡像LABEL:為鏡像添加元數(shù)據(jù)COPY:拷貝文件或目錄到鏡像中,跟 ADD 類似,但不具備自動下載或解壓的功能ADD:拷貝文件或目錄到鏡像中,如果是 URL 或壓縮包便會自動下載或自動解壓WORKDIR:指定工作目錄RUN:指定 docker build 過程中運行的程序VOLUME:指定容器掛載點EXPOSE:聲明容器的服務端口(僅僅是聲明)ENV:設置環(huán)境變量CMD:運行容器時執(zhí)行的命令ENTRYPOINT:運行容器時程序入口ARG:指定構(gòu)建時的參數(shù)USER:指定當前用戶HEALTHCHECK:健康檢測指令
2.2 命令詳解
功能:
FROM 指令用于為鏡像文件構(gòu)建過程指定基礎(chǔ)鏡像,后續(xù)的指令運行于此基礎(chǔ)鏡像所提供的運行環(huán)境;
注意事項:
FROM指令必須是 Dockerfile 中非注釋行或者ARG之后的第一個指令;- 實踐中,基準鏡像可以是任何可用鏡像文件,默認情況下,
docker build會在 docker 主機上查找指定的鏡像文件,在其不存在時,則會自動從 Docker 的公共庫 pull 鏡像下來。如果找不到指定的鏡像文件,docker build會返回一個錯誤信息; FROM可以在一個 Dockerfile 中出現(xiàn)多次,如果有需求在一個 Dockerfile 中創(chuàng)建多個鏡像,或?qū)⒁粋€構(gòu)建階段作為另一個的依賴;- 如果
FROM語句沒有指定鏡像標簽,則默認使用latest標簽。
語法:
FROM [--platform=<platform>] <image> [AS <name>] FROM [--platform=<platform>] <image>[:<tag>] [AS <name>] FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
參數(shù):
<platform>:構(gòu)建的 cpu 架構(gòu),如linux/amd64,linux/arm64,windows/amd64<image>: 指定作為 base image 的名稱;<tag>: base image 的標簽,省略時默認latest;<digest>: 是鏡像的哈希碼;AS <name>: 指定構(gòu)建步驟的名稱,配合COPY --from=<name>可以完成多級構(gòu)建
示例:

注意:可在一個 Dockerfile 中多次使用FROM指令,每個FROM指令開啟一個新的構(gòu)建階段。每個階段都可以有自己的安裝、配置和構(gòu)建步驟。后面的構(gòu)建階段可以從前面的構(gòu)建階段中選擇性地復制所需的文件或目錄。即“多階段構(gòu)建”
LABEL
功能:
為鏡像添加元數(shù)據(jù)
語法:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:
FROM ubuntu:22.04 as buildstage1 LABEL version="1.0" desc="create by bit"
COPY
功能:
用于從 docker 主機復制新文件或者目錄至創(chuàng)建的新鏡像指定路徑中。
語法:
COPY [--chown=<user>:<group>] <src>... <dest> COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
參數(shù):
<src>:要復制的源文件或目錄,支持使用通配符;<dest>:目標路徑,即正在創(chuàng)建的 image 的文件系統(tǒng)路徑;建議<dest>使用絕對路徑,否則,COPY 指定以 WORKDIR 為當前路徑
在路徑中有空白字符時,通常使用第 2 種格式;--chown:修改用戶和組--from <name>可選項:可以從之前構(gòu)建的步驟中拷貝內(nèi)容,結(jié)合FROM ... AS <name>往往用作多級構(gòu)建,后續(xù)我們有實戰(zhàn)課專門完成多級構(gòu)建
注意:
<src>必須是 build 上下文中的路徑,不能是其父目錄中的文件;- 如果
<src>是目錄,則其內(nèi)部文件或子目錄會被遞歸復制,但<src>目錄自身不會被復制; - 如果指定了多個
<src>,或在<src>中使用了通配符,則<dest>必須是一個目錄,且必須以/結(jié)尾; - 如果
<dest>事先不存在,它將會被自動創(chuàng)建,這包括父目錄路徑。
示例:

效果:

ENV
功能:
- 用于為鏡像定義所需的環(huán)境變量,并可被 Dockerfile 文件中位于其后的其它指令(如 ENV、ADD、COPY 等)所調(diào)用
- 調(diào)用格式為
$variable_name或${variable_name}
語法:
ENV <key>=<value> ...
示例:

效果:

與ENV配合使用:
ENV MYROOTDIR=/data/web/html/
COPY ./index.html ${MYROOTDIR}
WORKDIR
功能:
為 Dockerfile 中所有的 RUN、CMD、ENTRYPOINT、COPY 和 ADD 指定設定工作目錄,相當于cd到一個目錄然后執(zhí)行指令
語法:
WORKDIR /path/to/workdir
注意:
- 默認的工作目錄是
/ - 如果提供了相對路徑,它將相對于前一條
WORKDIR指令的路徑。 WORKDIR指令可以解析先前使用設置的環(huán)境變量ENV
示例:

效果:

注意:在 Dockerfile 中,如果存在多個 WORKDIR 指令,在后續(xù)的 WORKDIR 指令出現(xiàn)之前,所有需要指定工作目錄的指令(如 RUN、CMD、ENTRYPOINT、COPY、ADD 等)都會以上一個 WORKDIR 所設置的路徑作為工作目錄。
ADD
功能:
ADD 指令類似于 COPY 指令,ADD 支持使用 TAR 文件和 URL 路徑,會自動完成解壓和下載,而copy不支持這個功能
語法:
ADD [--chown=<user>:<group>] <src>... <dest> ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
參數(shù):
<src>:要復制的源文件或目錄,支持使用通配符;<dest>:目標路徑,即正在創(chuàng)建的 image 的文件系統(tǒng)路徑;建議<dest>使用絕對路徑,否則,ADD 指定以 WORKDIR 為起始路徑;在路徑中有空白字符時,通常使用第 2 種格式;--chown:修改用戶和組
示例:

效果:

如果是本地下載tar,然后給容器會自動解壓。如果是遠端則不會。
RUN
功能:
用于指定 docker build 過程中運行的程序,其可以是任何命令
語法:
#shell form RUN <command> #exec form RUN ["executable", "param1", "param2"]
參數(shù):
第一種格式中,<command>通常是一個 shell 命令,且以/bin/sh -c來運行它,Windows 默認為 cmd /S /C。如果一個腳本 test.sh 不能自己執(zhí)行,必須要 /bin/sh -c test.sh 的方式來執(zhí)行,那么,如果使用 RUN 的 shell 形式,最后得到的命令相當于:
/bin/sh -c "/bin/sh -c 'test.sh'"
第二種語法格式中的參數(shù)是一個 JSON 格式的數(shù)組,其中<executable>為要運行的命令,后面的 <paramN>為傳遞給命令的選項或參數(shù);然而,此種格式指定的命令不會以/bin/sh -c來發(fā)起,因此常見的 shell 操作如變量替換以及通配符(?,*等)替換將不會進行;不過,如果要運行的命令依賴于此 shell 特性的話,可以將其替換為類似下面的格式。
RUN ["/bin/bash", "-c", "<executable>", "<param1>"]
示例:

注意:多使用&&把指令放在同一個RUN,減少層
CMD
功能:
- 類似于
RUN指令,CMD指令也可用于運行任何命令或應用程序,不過,二者的運行時間點不同 RUN指令運行于映像文件構(gòu)建過程中,而CMD指令運行于基于Dockerfile構(gòu)建出的新映像文件啟動一個容器時CMD指令的首要目的在于為啟動的容器指定默認要運行的程序,且其運行結(jié)束后,容器也將終止;不過,CMD指定的命令其可以被docker run的命令行選項所覆蓋- 在
Dockerfile中可以存在多個CMD指令,但僅最后一個會生效
語法:
CMD ["executable","param1","param2"] (exec form, this is the preferred form) CMD ["param1","param2"] (as default parameters to ENTRYPOINT) CMD command param1 param2 (shell form)
注意:
- 第二種則用于為
ENTRYPOINT指令提供默認參數(shù) - json 數(shù)組中,要使用雙引號,單引號會出錯
示例:
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
ENTRYPOINT
功能:
用于指定容器的啟動入口
語法:
#exec form ENTRYPOINT ["executable", "param1", "param2"] # shell form ENTRYPOINT command param1 param2
參數(shù):
json 數(shù)組中,要使用雙引號,單引號會出錯
注意:ENTRYPOINT與CMD功能類似,但ENTRYPOINT不會被docker run指令完全覆蓋,docker run后面的參數(shù)會作為ENTRYPOINT的參數(shù)。
示例:
test:v0.7使用CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
test:v0.8使用ENTRYPOINT ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

EXPOSE
功能:
- 用于為容器聲明打開指定要監(jiān)聽的端口以實現(xiàn)與外部通信
- 該
EXPOSE指令實際上并不發(fā)布端口。它充當構(gòu)建圖像的人和運行容器的人之間的一種文檔,關(guān)于要發(fā)布哪些端口。要在運行容器時實際發(fā)布端口,使用-p參數(shù)發(fā)布和映射一個或多個端口,或者使用-Pflag 發(fā)布所有暴露的端口并將它們映射宿主機端口。
語法:
EXPOSE <port> [<port>/<protocol>...]
參數(shù):
<protocol>:tcp/udp 協(xié)議<port>:端口
示例:
EXPOSE 80/tcp
ARG
功能:
ARG指令類似ENV,定義了一個變量;區(qū)別于ENV:用戶可以在構(gòu)建時docker build --build-arg <varname> = <value>進行對變量的修改;ENV不可以;- 如果用戶指定了未在
Dockerfile中定義的構(gòu)建參數(shù),那么構(gòu)建輸出警告。
語法:
ARG <name>[=<default value>]
注意:
Dockerfile可以包含一個或多個ARG指令ARG支持指定默認值- 使用范圍:定義之后才能使用,定義之前為空,如下面的案例,執(zhí)行命令
docker build --build-arg username=what_user .第二行計算結(jié)果為some_user,不是我們指定的build-arg中的參數(shù)值what_user
注意:ARG和ENV同時存在時,ENV會覆蓋ARG
示例:
Dockerfile文件
ARG SYSVERSION=22.04
FROM ubuntu:${SYSVERSION}
構(gòu)建時可以更改變量從而更改Ubuntu版本:
docker build -t test:v0.9 --build-arg SYSVERSION=22.10
VOLUME
功能:
- 用于在 image 中創(chuàng)建一個掛載點目錄
- 通過
VOLUME指令創(chuàng)建的掛載點,無法指定主機上對應的目錄,是自動生成的。
語法:
VOLUME <mountpoint> VOLUME ["<mountpoint>"]
參數(shù):
mountpoint: 掛載點目錄
注意:
- 如果掛載點目錄路徑下此前有文件存在,
docker run命令會在卷掛載完成后將此前的所有文件復制到新掛載的卷中 - 其實
VOLUME指令只是起到了聲明容器中的目錄作為匿名卷,但是并沒有將匿名卷綁定到宿主機指定目錄的功能。 volume只是指定了一個目錄,用以在用戶忘記啟動時指定-v參數(shù)也可以保證容器的正常運行。比如mysql,你不能說用戶啟動時沒有指定-v,然后刪了容器,就把mysql的數(shù)據(jù)文件都刪了,那樣生產(chǎn)上是會出大事故的,所以mysql的dockerfile里面就需要配置volume,這樣即使用戶沒有指定-v,容器被刪后也不會導致數(shù)據(jù)文件都不在了。還是可以恢復的。volume與-v指令一樣,容器被刪除以后映射在主機上的文件不會被刪除。- 如果
-v和volume指定了同一個位置,會以-v設定的目錄為準,其實volume指令的設定的目的就是為了避免用戶忘記指定-v的時候?qū)е碌臄?shù)據(jù)丟失,那么如果用戶指定了-v,自然而然就不需要volume指定的位置了。
示例:
VOLUME ["/data1"]
USER
功能:
- 用于指定運行 image 時的或運行 Dockerfile 中任何
RUN、CMD或ENTRYPOINT指令定的程序時的用戶名或 UID - 默認情況下,container 的運行身份為 root 用戶
語法:
USER <user>[:<group>] USER <UID>[:<GID>]
參數(shù):
- user: 用戶
- group: 用戶組
- uid: 用戶 id
- gid: 組 id
注意:
<UID>可以為任意數(shù)字,但實踐中其必須為/etc/passwd中某用戶的有效UID,否則將運行失敗
示例:
USER root:root RUN groupadd mysql RUN useradd mysql -g mysql USER mysql:mysql RUN whoami > /tmp/user.txt
HEALTHCHECK
功能:
HEALTHCHECK指令告訴 Docker 如何測試容器以檢查它是否仍在工作。- 即使服務器進程仍在運行,這也可以檢測出陷入無限循環(huán)且無法處理新連接的 Web 服務器等情況。
語法:
HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container) HEALTHCHECK NONE (disable any healthcheck inherited from the base image)
OPTIONS 選項參數(shù):
--interval=DURATION(default: 30s):每隔多長時間探測一次,默認 30 秒--timeout= DURATION(default: 30s):服務響應超時時長,默認 30 秒--start-period= DURATION(default: 0s):服務啟動多久后開始探測,默認 0 秒--retries=N(default: 3):認為檢測失敗幾次為宕機,默認 3 次
返回值:
- 0:容器成功是健康的,隨時可以使用
- 1:不健康的容器無法正常工作
- 2:保留不使用此退出代碼
示例:
FROM nginx:1.24.0 HEALTHCHECK --interval=5s --timeout=3s \ CMD curl -fs http://localhost/ || exit 1
三、docker build 指令
功能:
docker build 命令用于使用 Dockerfile 創(chuàng)建鏡像。
語法:
docker build [OPTIONS] PATH | URL | -
關(guān)鍵參數(shù):
--build-arg=[]:設置鏡像創(chuàng)建時的變量;-f:指定要使用的 Dockerfile 路徑;--label=[]:設置鏡像使用的元數(shù)據(jù);--no-cache:創(chuàng)建鏡像的過程不使用緩存;--pull:嘗試去更新鏡像的新版本;--quiet, -q:安靜模式,成功后只輸出鏡像 ID;--tag, -t:鏡像的名字及標簽,通常name:tag或者name格式;可以在一次構(gòu)建中為一個鏡像設置多個標簽。--network:默認default。在構(gòu)建期間設置RUN指令的網(wǎng)絡模式
以上就是Docker利用Dockerfile與docker build命令構(gòu)建鏡像指南的詳細內(nèi)容,更多關(guān)于Docker構(gòu)建鏡像的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于docker部署的jenkins跑git上的程序的問題
這篇文章主要介紹了docker部署的jenkins跑git上的程序的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11
docker-compose部署mysql數(shù)據(jù)庫完整步驟
Docker-Compose項目是Docker官方的開源項目,負責實現(xiàn)對Docker容器集群的快速編排,這篇文章主要給大家介紹了關(guān)于docker-compose部署mysql數(shù)據(jù)庫的完整步驟,需要的朋友可以參考下2024-05-05
解決docker加載新的鏡像后repository和tag名稱都為none的問題
這篇文章主要介紹了解決docker加載新的鏡像后repository和tag名稱都為none的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
使用docker?compose一鍵部署WordPress博客的方法
這篇文章主要介紹了docker-compose一鍵部署WordPress博客,本文分步驟給大家講解的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04
Docker容器無法被stop or kill問題的解決方法
這篇文章主要介紹了Docker容器無法被stop or kill問題的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-09-09

