Docker的那些事兒—Dockerfile常用指令(13)


上一篇:Docker的那些事兒—docker commit與docker build比較(12)


Dockerfile是由一行行命令語句組成绝编,并且支持以#開頭的注釋行。

一般的,Dockerfile分為四部分:基礎鏡像信息、維護者信息、鏡像操作指令和容器啟動時執(zhí)行指令哎壳。通過一個例子看下:


FROM debian:stretch-slim

LABEL maintainer="NGINX Docker Maintainers "

ENVNGINX_VERSION 1.13.8-1~stretch

ENVNJS_VERSION? 1.13.8.0.1.15-1~stretch

RUN set-x \

? ? ? && apt-get update \

? ? ? && apt-get install --no-install-recommends --no-install-suggests -y gnupg1 \

? ? ? && \

? ? ? NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62;\

? ? ? found=''; \

? ? ? for server in \

? ? ? ? ? ? ? ha.pool.sks-keyservers.net \

? ? ? ? ? ? ? hkp://keyserver.ubuntu.com:80 \

? ? ? ? ? ? ? hkp://p80.pool.sks-keyservers.net:80\

? ? ? ? ? ? ? pgp.mit.edu \

? ? ? ; do \

? ? ? ? ? ? ? echo "Fetching GPG key$NGINX_GPGKEY from $server"; \

? ? ? ? ? ? ? apt-key adv --keyserver"$server" --keyserver-options timeout=10 --recv-keys"$NGINX_GPGKEY" && found=yes && break; \

? ? ? done; \

? ? ? test -z "$found" &&echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY"&& exit 1; \

? ? ? apt-get remove --purge --auto-remove -ygnupg1 && rm -rf /var/lib/apt/lists/* \

? ? ? && dpkgArch="$(dpkg--print-architecture)" \

? ? ? && nginxPackages=" \

? ? ? ? ? ? ? nginx=${NGINX_VERSION} \

? ? ? ? ? ? ? nginx-module-xslt=${NGINX_VERSION}\

? ? ? ? ? ? ? nginx-module-geoip=${NGINX_VERSION}\

? ? ? ? ? ? ? nginx-module-image-filter=${NGINX_VERSION}\

? ? ? ? ? ? ? nginx-module-njs=${NJS_VERSION} \

? ? ? " \

? ? ? && case "$dpkgArch" in\

? ? ? ? ? ? ? amd64|i386) \

# archesofficialy built by upstream

? ? ? ? ? ? ? ? ? ? echo "debhttp://nginx.org/packages/mainline/debian/ stretch nginx" >>/etc/apt/sources.list \

? ? ? ? ? ? ? ? ? ? && apt-get update \

? ? ? ? ? ? ? ? ? ? ;; \

? ? ? ? ? ? ? *) \

# we'reon an architecture upstream doesn't officially build for

# let'sbuild binaries from the published source packages

? ? ? ? ? ? ? ? ? ? echo "deb-srchttp://nginx.org/packages/mainline/debian/ stretch nginx" >>/etc/apt/sources.list \

? ? ? ? ? ? ? ? ? ? \

# newdirectory for storing sources and .deb files

? ? ? ? ? ? ? ? ? ? &&tempDir="$(mktemp -d)" \

? ? ? ? ? ? ? ? ? ? && chmod 777"$tempDir" \

# (777 toensure APT's "_apt" user can access it too)

? ? ? ? ? ? ? ? ? ? \

# savelist of currently-installed packages so build dependencies can be cleanlyremoved later

? ? ? ? ? ? ? ? ? ? && savedAptMark="$(apt-markshowmanual)" \

? ? ? ? ? ? ? ? ? ? \

# build.deb files from upstream's source packages (which are verified by apt-get)

? ? ? ? ? ? ? ? ? ? && apt-get update \

? ? ? ? ? ? ? ? ? ? && apt-getbuild-dep -y $nginxPackages \

? ? ? ? ? ? ? ? ? ? && ( \

? ? ? ? ? ? ? ? ? ? ? ? ? ? cd"$tempDir" \

? ? ? ? ? ? ? ? ? ? ? ? ? ? &&DEB_BUILD_OPTIONS="nocheck parallel=$(nproc)" \

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? apt-getsource --compile $nginxPackages \

? ? ? ? ? ? ? ? ? ? ) \

# wedon't remove APT lists here because they get re-downloaded and removed later

? ? ? ? ? ? ? ? ? ? \

# resetapt-mark's "manual" list so that "purge --auto-remove" willremove all build dependencies

# (whichis done after we install the built packages so we don't have to redownload anyoverlapping dependencies)

? ? ? ? ? ? ? ? ? ? && apt-markshowmanual | xargs apt-mark auto > /dev/null \

? ? ? ? ? ? ? ? ? ? && { [ -z"$savedAptMark" ] || apt-mark manual $savedAptMark; } \

? ? ? ? ? ? ? ? ? ? \

# createa temporary local APT repo to install from (so that dependency resolution canbe handled by APT, as it should be)

? ? ? ? ? ? ? ? ? ? && ls -lAFh"$tempDir" \

? ? ? ? ? ? ? ? ? ? && ( cd"$tempDir" && dpkg-scanpackages . > Packages ) \

? ? ? ? ? ? ? ? ? ? && grep '^Package:' "$tempDir/Packages" \

? ? ? ? ? ? ? ? ? ? && echo "deb [trusted=yes ] file://$tempDir ./" > /etc/apt/sources.list.d/temp.list \

# workaround the following APT issue by using "Acquire::GzipIndexes=false"(overriding "/etc/apt/apt.conf.d/docker-gzip-indexes")

#? Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages- open (13: Permission denied)

#? ...

#? E: Failed to fetchstore:/var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages? Could not open file/var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permissiondenied)

? ? ? ? ? ? ? ? ? ? && apt-get -oAcquire::GzipIndexes=false update \

? ? ? ? ? ? ? ? ? ? ;; \

? ? ? esac \

? ? ? \

? ? ? && apt-get install--no-install-recommends --no-install-suggests -y \

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? $nginxPackages\

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? gettext-base\

? ? ? && rm -rf /var/lib/apt/lists/* \

? ? ? \

# if wehave leftovers from building, let's purge them (including extra, unnecessarybuild deps)

? ? ? && if [ -n "$tempDir"]; then \

? ? ? ? ? ? ? apt-get purge -y --auto-remove \

? ? ? ? ? ? ? && rm -rf"$tempDir" /etc/apt/sources.list.d/temp.list; \

? ? ? fi

# forwardrequest and error logs to docker log collector

RUN ln-sf /dev/stdout /var/log/nginx/access.log \

? ? ? && ln -sf /dev/stderr/var/log/nginx/error.log


EXPOSE 80

STOPSIGNALSIGTERM

CMD["nginx", "-g", "daemon off;"]


指令的一般格式為INSTRUCTION arguments,指令包括 FROM、 MAINTAINER攘滩、RUN 等。INSTRUCTION實際上是不區(qū)分大小寫的纸泡,只所以寫成大寫是為了區(qū)別于后面的arguments漂问。

FROM

格式為:

? ? FROM image

? ? FROM image:tag

Docker逐條運行Dockerfile中的指令。第一條指令必須為FROM指令女揭。并且如果在同一個Dockerfile中創(chuàng)建多個鏡像時蚤假,可以使用多個FROM指令(每個鏡像一次)。

MAINTAINER

格式為:

? ? MAINTAINER name

指定維護者信息吧兔。

ENV

格式為:

? ? ENV key value

指定一個環(huán)境變量磷仰,并在容器運行時保持,環(huán)境變量可用于ADD境蔼、COPY灶平、ENV伺通、EXPOSE、FROM民逼、LABEL泵殴、USER、VOLUME拼苍、WORKDIR笑诅、ONBUILD指令中。

RUN

格式為:

? ? RUN command

? ? RUN ["executable","param1", "param2"]

前者將在shell終端中運行命令疮鲫,即/bin/sh -c吆你;后者則使用exec執(zhí)行。

指定使用其它終端可以通過第二種方式實現(xiàn)俊犯,例如 RUN ["/bin/bash", "-c", "echo hello"]妇多。每條 RUN 指令將在當前鏡像基礎上執(zhí)行指定命令,并提交為新的鏡像燕侠。當命令較長時可以使用 \ 來換行者祖。例如:


RUN apt-get update && apt-getinstall -y --no-install-recommends \

? ? ? ? ? ? ? g++\

? ? ? ? ? ? ? gcc\

? ? ? ? ? ? ? libc6-dev\

? ? ? ? ? ? ? make\

? ? ? ? ? ? ? pkg-config\

? ? ? &&rm -rf /var/lib/apt/lists/*


CMD

支持三種格式:

? ? CMD ["executable","param1","param2"] 使用exec執(zhí)行,推薦方式绢彤;

? ? CMD command param1 param2在/bin/sh中執(zhí)行七问,提供給需要交互的應用;

? ? CMD ["param1","param2"] 提供給ENTRYPOINT的默認參數(shù)茫舶;

指定啟動容器時執(zhí)行的命令械巡,每個Dockerfile 只能有一條CMD命令。如果指定了多條命令饶氏,只有最后一條會被執(zhí)行讥耗。如果用戶啟動容器時候指定了運行的命令,則會覆蓋掉CMD指定的命令疹启。

LABEL

格式為:

? ? LABEL key=value key=value ...

LABEL指令增加元數(shù)據(jù)到鏡像中古程。可以通過docker inspect imageID查看:

EXPOSE

格式為:

? ? EXPOSE port [port...]

告訴Docker服務端容器暴露的端口號喊崖。在啟動容器時需要通過-P指定籍琳,Docker主機會自動分配一個端口轉發(fā)到指定的端口。

ADD

格式為:

? ? ADD src dest

該命令將復制指定的src到容器中的dest贷祈。 其中src可以是Dockerfile所在目錄的一個相對路徑趋急;也可以是一個URL;還可以是一個tar文件(自動解壓為目錄)势誊。

COPY

格式為:

? ? COPY src dest

復制本地主機的src(為Dockerfile所在目錄的相對路徑)到容器中的 dest呜达。當使用本地目錄為源目錄時,推薦使用COPY粟耻。

ENTRYPOINT

兩種格式:

? ? ENTRYPOINT ["executable", "param1", "param2"]

? ? ENTRYPOINT command param1 param2 (shell中執(zhí)行)

配置容器啟動后執(zhí)行的命令查近,并且不可被docker run提供的參數(shù)覆蓋眉踱。每個Dockerfile中只能有一個ENTRYPOINT,當指定多個時霜威,只有最后一個起效谈喳。

VOLUME

格式為:

? ? VOLUME ["/data"]

創(chuàng)建一個可以從本地主機或其他容器掛載的掛載點,一般用來存放數(shù)據(jù)庫和需要保持的數(shù)據(jù)等戈泼。

USER

格式為:

? ? USER daemon

指定運行容器時的用戶名或UID婿禽,后續(xù)的RUN也會使用指定用戶。當服務不需要管理員權限時大猛,可以通過該命令指定運行用戶扭倾。并且可以在之前創(chuàng)建所需要的用戶,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres挽绩。

WORKDIR

格式為:

? ? WORKDIR /path/to/workdir

為后續(xù)的RUN膛壹、CMD、ENTRYPOINT指令配置工作目錄唉堪。

可以使用多個WORKDIR指令模聋,后續(xù)命令如果參數(shù)是相對路徑,則會基于之前命令指定的路徑唠亚。例如:


WORKDIR /a

WORKDIR b

WORKDIR c

RUN pwd


則最終路徑為/a/b/c链方。

ONBUILD

格式為:

? ? ONBUILD [INSTRUCTION]

配置當所創(chuàng)建的鏡像作為其它新創(chuàng)建鏡像的基礎鏡像時,所執(zhí)行的操作指令趾撵。

例如,Dockerfile使用如下的內容創(chuàng)建了鏡像image-A共啃。


[...]

ONBUILD ADD . /app/src

ONBUILD RUN /usr/local/bin/python-build --dir /app/src

[...]


如果基于image-A創(chuàng)建新的鏡像時占调,新的Dockerfile中使用FROM image-A 指定基礎鏡像時,會自動執(zhí)行ONBUILD指令內容移剪,等價于在后面添加了兩條指令究珊。


FROM image-A

#Automatically run the following

ADD . /app/src

RUN /usr/local/bin/python-build --dir /app/src


使用ONBUILD指令的鏡像,推薦在標簽中注明纵苛,例如ruby:1.9-onbuild或者ruby:2.0-onbuild剿涮。



下一篇:Docker的那些事兒—利用Docker Hub自動構建鏡像(14)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市攻人,隨后出現(xiàn)的幾起案子取试,更是在濱河造成了極大的恐慌,老刑警劉巖怀吻,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瞬浓,死亡現(xiàn)場離奇詭異,居然都是意外死亡蓬坡,警方通過查閱死者的電腦和手機猿棉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門磅叛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萨赁,你說我怎么就攤上這事弊琴。” “怎么了杖爽?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵敲董,是天一觀的道長。 經(jīng)常有香客問我掂林,道長臣缀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任泻帮,我火速辦了婚禮精置,結果婚禮上,老公的妹妹穿的比我還像新娘锣杂。我一直安慰自己脂倦,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布元莫。 她就那樣靜靜地躺著赖阻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪踱蠢。 梳的紋絲不亂的頭發(fā)上火欧,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音茎截,去河邊找鬼苇侵。 笑死,一個胖子當著我的面吹牛企锌,可吹牛的內容都是我干的榆浓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼撕攒,長吁一口氣:“原來是場噩夢啊……” “哼陡鹃!你這毒婦竟也來了?” 一聲冷哼從身側響起抖坪,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤萍鲸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后擦俐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猿推,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蹬叭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片藕咏。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖秽五,靈堂內的尸體忽然破棺而出孽查,到底是詐尸還是另有隱情,我是刑警寧澤坦喘,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布盲再,位于F島的核電站,受9級特大地震影響瓣铣,放射性物質發(fā)生泄漏答朋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一棠笑、第九天 我趴在偏房一處隱蔽的房頂上張望梦碗。 院中可真熱鬧,春花似錦蓖救、人聲如沸洪规。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斩例。三九已至,卻和暖如春从橘,著一層夾襖步出監(jiān)牢的瞬間念赶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工恰力, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留叉谜,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓牺勾,卻偏偏與公主長得像正罢,于是被迫代替她去往敵國和親阵漏。 傳聞我的和親對象是個殘疾皇子驻民,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容

  • 轉載自 http://blog.opskumu.com/docker.html 一、Docker 簡介 Docke...
    極客圈閱讀 10,476評論 0 120
  • Docker — 云時代的程序分發(fā)方式 要說最近一年云計算業(yè)界有什么大事件履怯?Google Compute Engi...
    ahohoho閱讀 15,511評論 15 147
  • docker基本概念 1. Image Definition 鏡像 Image 就是一堆只讀層 read-only...
    慢清塵閱讀 8,728評論 1 21
  • 去年秋回还,偶然看到小姐姐們做的各式手帳,開始入了手帳這個坑叹洲。 開始的理由 平時也會寫一些東西柠硕,但分散在各個地方:手機...
    斐碩人閱讀 399評論 1 4
  • 霹靂混沌開,萬物無由生。 千載山河變蝗柔,輪回浮生夢闻葵。 天道未可知,吾生隨吾心癣丧。 欲念如烈火槽畔,消長似無盡。 縱禁幾十年...
    哲修潯閱讀 207評論 2 2