Dockerfile 指令詳解

官方倉(cāng)庫(kù)示例

這些官方倉(cāng)庫(kù)的 Dockerfile 都是參考典范:https://github.com/docker-library/docs

COPY 復(fù)制文件

  • COPY <源路徑>... <目標(biāo)路徑>
  • COPY ["<源路徑1>",... "<目標(biāo)路徑>"]
和 RUN 指令一樣,也有兩種格式,一種類似于命令行,一種類似于函數(shù)調(diào)用。

COPY 指令將從構(gòu)建上下文目錄中 <源路徑> 的文件/目錄復(fù)制到新的一層的鏡像內(nèi)的 <目標(biāo)路徑> 位置。比如:

COPY package.json /usr/src/app/
<源路徑> 可以是多個(gè),甚至可以是通配符,其通配符規(guī)則要滿足 Go 的 filepath.Match 規(guī)則,如:

COPY hom* /mydir/
COPY hom?.txt /mydir/
<目標(biāo)路徑> 可以是容器內(nèi)的絕對(duì)路徑,也可以是相對(duì)于工作目錄的相對(duì)路徑(工作目錄可以用 WORKDIR 指令來指定)。目標(biāo)路徑不需要事先創(chuàng)建,如果目錄不存在會(huì)在復(fù)制文件前先行創(chuàng)建缺失目錄。

此外,還需要注意一點(diǎn),使用 COPY 指令,源文件的各種元數(shù)據(jù)都會(huì)保留。比如讀、寫、執(zhí)行權(quán)限、文件變更時(shí)間等。這個(gè)特性對(duì)于鏡像定制很有用。特別是構(gòu)建相關(guān)文件都在使用 Git 進(jìn)行管理的時(shí)候。

ADD 更高級(jí)的復(fù)制文件

如果 <源路徑> 為一個(gè) tar 壓縮文件的話,壓縮格式為 gzip, bzip2 以及 xz 的情況下,ADD 指令將會(huì)自動(dòng)解壓縮這個(gè)壓縮文件到 <目標(biāo)路徑> 去。

在某些情況下,這個(gè)自動(dòng)解壓縮的功能非常有用,比如官方鏡像 ubuntu 中:

FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
在 Docker 官方的 Dockerfile 最佳實(shí)踐文檔 中要求,盡可能的使用 COPY,因?yàn)?COPY 的語義很明確,就是復(fù)制文件而已,而 ADD 則包含了更復(fù)雜的功能,其行為也不一定很清晰。最適合使用 ADD 的場(chǎng)合,就是所提及的需要自動(dòng)解壓縮的場(chǎng)合。
因此在 COPY 和 ADD 指令中選擇的時(shí)候,可以遵循這樣的原則,所有的文件復(fù)制均使用 COPY 指令,僅在需要自動(dòng)解壓縮的場(chǎng)合使用 ADD。

CMD 容器啟動(dòng)命令

CMD 指令的格式和 RUN 相似,也是兩種格式:

  • shell 格式:CMD <命令>
  • exec 格式:CMD ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"...]
  • 參數(shù)列表格式:CMD ["參數(shù)1", "參數(shù)2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具體的參數(shù)。

在指令格式上,一般推薦使用 exec 格式,這類格式在解析時(shí)會(huì)被解析為 JSON 數(shù)組,因此一定要使用雙引號(hào) ",而不要使用單引號(hào)。

果使用 shell 格式的話,實(shí)際的命令會(huì)被包裝為 sh -c 的參數(shù)的形式進(jìn)行執(zhí)行。比如:

CMD echo $HOME

在實(shí)際執(zhí)行中,會(huì)將其變更為:

CMD [ "sh", "-c", "echo $HOME" ]

ENV 設(shè)置環(huán)境變量

格式有兩種:

  • ENV <key> <value>
  • ENV <key1>=<value1> <key2>=<value2>...

這個(gè)指令很簡(jiǎn)單,就是設(shè)置環(huán)境變量而已,無論是后面的其它指令,如 RUN,還是運(yùn)行時(shí)的應(yīng)用,都可以直接使用這里定義的環(huán)境變量。

ENV VERSION=1.0 DEBUG=on \
    NAME="Happy Feet"
ENV NODE_VERSION 7.2.0

RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
  && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
  && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
  && grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
  && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \
  && rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
  && ln -s /usr/local/bin/node /usr/local/bin/nodejs
這里先定義了環(huán)境變量 NODE_VERSION,其后的 RUN 這層里,多次使用 $NODE_VERSION 來進(jìn)行操作定制??梢钥吹?,將來升級(jí)鏡像構(gòu)建版本的時(shí)候,只需要更新 7.2.0 即可,Dockerfile 構(gòu)建維護(hù)變得更輕松了。

VOLUME 定義匿名卷

格式為:

  • VOLUME ["<路徑1>", "<路徑2>"...]
  • VOLUME <路徑>
VOLUME /data

這里的 /data 目錄就會(huì)在運(yùn)行時(shí)自動(dòng)掛載為匿名卷,任何向 /data 中寫入的信息都不會(huì)記錄進(jìn)容器存儲(chǔ)層,從而保證了容器存儲(chǔ)層的無狀態(tài)化。當(dāng)然,運(yùn)行時(shí)可以覆蓋這個(gè)掛載設(shè)置。比如:

docker run -d -v mydata:/data xxxx

在這行命令中,就使用了 mydata 這個(gè)命名卷掛載到了 /data 這個(gè)位置,替代了 Dockerfile 中定義的匿名卷的掛載配置。

EXPOSE 暴露端口

格式為 EXPOSE <端口1> [<端口2>...]。

WORKDIR 指定工作目錄

  • 格式為 WORKDIR <工作目錄路徑>。

Dockerfile 等同于 Shell 腳本來書寫,這種錯(cuò)誤的理解還可能會(huì)導(dǎo)致出現(xiàn)下面這樣的錯(cuò)誤:

RUN cd /app
RUN echo "hello" > world.txt

Dockerfile 參考文檔

Dockerfie 官方文檔:https://docs.docker.com/engine/reference/builder/
Dockerfile 最佳實(shí)踐文檔:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/
Docker 官方鏡像 Dockerfile:https://github.com/docker-library/docs
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、Docker創(chuàng)建鏡像的方式有兩種: 一種通過commit的方式:把做了一系列操作的容器關(guān)閉,然后利用docke...
    jie0112閱讀 3,911評(píng)論 0 3
  • 縱有千金何道富,不如復(fù)載五車書 Dockerfile文件由一些列的指令組成,它是用來構(gòu)建docker鏡像的,類似于...
    olaH閱讀 1,293評(píng)論 2 5
  • FROM FROM 指定基礎(chǔ)鏡像,因此一個(gè) Dockerfile 中 FROM 是必備的指令,并且必須是第一條指令...
    IT白閱讀 392評(píng)論 0 0
  • Dockerfile有十多個(gè)指令。本節(jié)我們來系統(tǒng)講解這些指令,指令的一般格式為指令名稱 參數(shù) 。 ADD 復(fù)制文件...
    周立_itmuch閱讀 500評(píng)論 0 1
  • 《望臨淄霧霾有感》 云起氤氳化不開,一片混沌睜眼猜。 晨光麗景遮羞布,疑是天宮落地來。
    濤聲依舊7170580閱讀 369評(píng)論 1 2

友情鏈接更多精彩內(nèi)容