這些建議旨在幫助您創(chuàng)建一個高效且可維護(hù)的Dockerfile。
一、FROM
盡可能使用當(dāng)前的官方鏡像作為鏡像的基礎(chǔ)。Docker推薦Alpine鏡像,因為它受到嚴(yán)格控制,體積?。壳安坏? MB),同時仍然是一個完整的Linux發(fā)行版。
FROM [--platform=<platform>] <image> [AS <name>]
or
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
or
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
FROM指令初始化新的構(gòu)建階段,并為后續(xù)指令設(shè)置基本鏡像。因此,有效的Dockerfile必須以FROM指令開頭。
鏡像可以是任何有效的鏡像——從公共存儲庫中提取鏡像尤其容易:
- ARG是Dockerfile中FROM之前的唯一指令
- FROM可以在單個Dockerfile中多次出現(xiàn),以創(chuàng)建多個鏡像,或者將一個構(gòu)建階段用作另一個的依賴項。只需在每條新的FROM指令之前記下提交輸出的最后一個鏡像ID即可。每個FROM指令都會清除先前指令創(chuàng)建的任何狀態(tài)。
- 可選地,可以通過將AS名稱添加到FROM指令來為新的構(gòu)建階段指定名稱。該名稱可以在隨后的FROM和COPY-FROM=<name>指令中使用,以引用在此階段構(gòu)建的鏡像。
- 標(biāo)記值或摘要值是可選的。如果省略其中任何一個,則默認(rèn)情況下構(gòu)建器將采用最新的標(biāo)記。如果生成器找不到標(biāo)記值,則返回一個錯誤。
可選的--platform標(biāo)志可用于在FROM引用多平臺映像的情況下指定鏡像的平臺。例如,linux/amd64、linux/arm64或windows/amd64。默認(rèn)情況下,將使用構(gòu)建請求的目標(biāo)平臺。全局構(gòu)建參數(shù)可以用于此標(biāo)志的值,例如,自動平臺ARG允許您將階段強(qiáng)制到本機(jī)構(gòu)建平臺(--platform=$BUILDPORM),并使用它交叉編譯到階段內(nèi)的目標(biāo)平臺。?
二、LABEL
您可以在鏡像中添加標(biāo)簽,以幫助按項目組織鏡像、記錄許可信息、幫助實現(xiàn)自動化或出于其他原因。對于每個標(biāo)簽,添加一行,以label開頭,包含一個或多個鍵值對。以下示例顯示了不同的可接受格式。解釋性意見包括在內(nèi)。
帶空格的字符串必須加引號或轉(zhuǎn)義空格。還必須轉(zhuǎn)義內(nèi)部引號字符(“)。例如:?
# Set one or more individual labels
LABEL com.example.version="0.0.1-beta"
LABEL vendor1="ACME Incorporated"
LABEL vendor2=ZENITH\ Incorporated
LABEL com.example.release-date="2015-02-12"
LABEL com.example.version.is-production=""
一個鏡像可以有多個標(biāo)簽。在Docker 1.10之前,建議將所有標(biāo)簽合并為一個LABEL指令,以防止創(chuàng)建額外的層。這不再是必要的,但仍然支持組合標(biāo)簽。例如:
# Set multiple labels on one line
LABEL com.example.version="0.0.1-beta" com.example.release-date="2015-02-12"
上面的例子也可以寫成:
# Set multiple labels at once, using line-continuation characters to break long lines
LABEL vendor=ACME\ Incorporated \
com.example.is-beta= \
com.example.is-production="" \
com.example.version="0.0.1-beta" \
com.example.release-date="2015-02-12"
三、RUN
將長的或復(fù)雜的RUN語句拆分到多行,用反斜杠分隔,使Dockerfile更具可讀性、可理解性和可維護(hù)性。
1、apt-get
RUN最常見的用例可能是apt-get的應(yīng)用程序。因為它安裝了軟件包,RUN-apt-get命令有幾個反直覺的行為需要注意。
總是在同一個RUN語句中結(jié)合RUN apt-get-update和apt-get-install。例如:
RUN apt-get update && apt-get install -y \
package-bar \
package-baz \
package-foo \
&& rm -rf /var/lib/apt/lists/*
在RUN語句中單獨(dú)使用apt-get-update會導(dǎo)致緩存問題和隨后的apt-get-install指令失敗。例如,此問題將出現(xiàn)在以下Dockerfile中:
# syntax=docker/dockerfile:1
FROM ubuntu:22.04
RUN apt-get update
RUN apt-get install -y curl
構(gòu)建鏡像后,所有層都在Docker緩存中。假設(shè)您稍后通過添加一個額外的包來修改apt-get-install,如以下Dockerfile所示:
# syntax=docker/dockerfile:1
FROM ubuntu:22.04
RUN apt-get update
RUN apt-get install -y curl nginx
Docker認(rèn)為初始指令和修改后的指令是相同的,并重用前面步驟中的緩存。因此,由于構(gòu)建使用了緩存版本,所以不會執(zhí)行apt-get更新。因為apt-get更新沒有運(yùn)行,所以您的構(gòu)建可能會得到curl和nginx包的過時版本。
使用RUN apt-get-update&&apt-get-install-y確保您的Dockerfile安裝最新的軟件包版本,無需進(jìn)一步編碼或手動干預(yù)。這種技術(shù)被稱為緩存破壞。您還可以通過指定包版本來實現(xiàn)緩存破壞。這就是所謂的版本固定。例如:
RUN apt-get update && apt-get install -y \
package-bar \
package-baz \
package-foo=1.3.*
版本固定強(qiáng)制構(gòu)建檢索特定版本,而不管緩存中有什么。這種技術(shù)還可以減少由于所需軟件包中的意外變化而導(dǎo)致的故障。
下面是一個格式良好的RUN說明,演示了所有的apt-get建議。文章來源:http://www.zghlxwxcb.cn/news/detail-776074.html
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
build-essential \
curl \
dpkg-sig \
libcap-dev \
libsqlite3-dev \
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.* \
&& rm -rf /var/lib/apt/lists/*
s3cmd參數(shù)指定版本1.1.*。如果映像以前使用的是舊版本,則指定新版本會導(dǎo)致apt-get-update的緩存中斷,并確保安裝新版本。在每行列出包也可以防止包重復(fù)中的錯誤。
此外,當(dāng)您通過刪除/var/lib/apt/lists來清理apt緩存時,它會減小鏡像大小,因為apt緩存不是存儲在層中的。由于RUN語句以apt-get-update開始,因此總是在安裝apt-get之前刷新包緩存。文章來源地址http://www.zghlxwxcb.cn/news/detail-776074.html
到了這里,關(guān)于Dockerfile 指令的最佳實踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!