docker鏡像多階段構(gòu)建

原文鏈接:Docker:使用多階段構(gòu)建鏡像

多階段構(gòu)建是 Docker 17.05 及更高版本提供的新功能叁怪。這對致力于優(yōu)化 Dockerfile 的人來說族展,使得 Dockerfile 易于閱讀和維護森缠。

在多階段構(gòu)建之前

關(guān)于構(gòu)建鏡像最具挑戰(zhàn)性的事情之一是保持鏡像體積小巧。 Dockerfile 中的每條指令都會在鏡像中增加一層仪缸,并且在移動到下一層之前贵涵,需要記住清除不需要的構(gòu)件。要編寫一個非常高效的 Dockerfile恰画,你通常需要使用 shell 技巧和其它方式來盡可能地減少層數(shù)宾茂,并確保每一層都具有上一層所需的構(gòu)件,而其它任何東西都不需要拴还。

實際上最常見的是刻炒,有一個 Dockerfile 用于開發(fā)(其中包含構(gòu)建應(yīng)用程序所需的所有內(nèi)容),而另一個裁剪過的用于生產(chǎn)環(huán)境自沧,它只包含您的應(yīng)用程序以及運行它所需的內(nèi)容。這被稱為“構(gòu)建器模式”树瞭。但是維護兩個 Dockerfile 并不理想拇厢。

下面分別是一個 Dockerfile.build 和遵循上面的構(gòu)建器模式的 Dockerfile 的例子:

Dockerfile.build:

FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
COPY app.go .
RUN go get -d -v golang.org/x/net/html \
  && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

注意這個例子還使用 Bash 的 && 運算符人為地將兩個 RUN 命令壓縮在一起,以避免在鏡像中創(chuàng)建額外的層晒喷。這很容易失敗孝偎,難以維護。例如凉敲,插入另一個命令時衣盾,很容易忘記繼續(xù)使用 \ 字符。

Dockerfile:

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY app .
CMD ["./app"]

build.sh:

#!/bin/sh
echo Building alexellis2/href-counter:build
docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \
    -t alexellis2/href-counter:build . -f Dockerfile.build
docker create --name extract alexellis2/href-counter:build
docker cp extract:/go/src/github.com/alexellis/href-counter/app ./app
docker rm -f extract
echo Building alexellis2/href-counter:latest
docker build --no-cache -t alexellis2/href-counter:latest .
rm ./app

當(dāng)您運行 build.sh 腳本時爷抓,它會構(gòu)建第一個鏡像势决,從中創(chuàng)建一個容器,以便將該構(gòu)件復(fù)制出來蓝撇,然后構(gòu)建第二個鏡像果复。 這兩個鏡像會占用您的系統(tǒng)的空間。

使用多階段構(gòu)建

在多階段構(gòu)建中渤昌,您需要在 Dockerfile 中多次使用 FROM 聲明虽抄。每次 FROM 指令可以使用不同的基礎(chǔ)鏡像,并且每次 FROM 指令都會開始新階段的構(gòu)建独柑。您可以選擇將構(gòu)件從一個階段復(fù)制到另一個階段迈窟,在最終鏡像中,不會留下您不需要的所有內(nèi)容忌栅。為了演示這是如何工作的车酣,讓我們調(diào)整前一節(jié)中的 Dockerfile 以使用多階段構(gòu)建。

Dockerfile:

FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]

您只需要單一個 Dockerfile。 不需要另外的構(gòu)建腳本骇径。只需運行 docker build 即可躯肌。

$ docker build -t alexellis2/href-counter:latest .

最終的結(jié)果是和以前體積一樣小的生產(chǎn)鏡像,復(fù)雜性顯著降低破衔。您不需要創(chuàng)建任何中間鏡像清女,也不需要將任何構(gòu)件提取到本地系統(tǒng)。

它是如何工作的呢晰筛?第二條 FROM 指令以 alpine:latest 鏡像作為基礎(chǔ)開始新的建造階段嫡丙。COPY --from=0 這一行將剛才前一個階段產(chǎn)生的構(gòu)件復(fù)制到這個新階段。Go SDK和任何中間構(gòu)件都被留在那里读第,而不會保存到最終的鏡像中曙博。

命名您的構(gòu)建階段

默認情況下,這些階段沒有命名怜瞒,您可以通過它們的整數(shù)來引用它們父泳,從第一個 FROM 指令的 0 開始。但是吴汪,你可以通過在 FROM 指令中使用 as來為階段命名惠窄。以下示例通過命名階段并在 COPY 指令中使用名稱來改進前一個示例。這意味著漾橙,即使您的 Dockerfile 中的指令稍后重新排序杆融,COPY 也不會出問題。

FROM golang:1.7.3 as builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go    .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末霜运,一起剝皮案震驚了整個濱河市脾歇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌淘捡,老刑警劉巖藕各,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異焦除,居然都是意外死亡座韵,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門踢京,熙熙樓的掌柜王于貴愁眉苦臉地迎上來誉碴,“玉大人,你說我怎么就攤上這事瓣距∈改澹” “怎么了旦袋?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長抖拴。 經(jīng)常有香客問我霜浴,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮思瘟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闻伶。我一直安慰自己滨攻,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布蓝翰。 她就那樣靜靜地躺著光绕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪畜份。 梳的紋絲不亂的頭發(fā)上诞帐,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音爆雹,去河邊找鬼停蕉。 笑死,一個胖子當(dāng)著我的面吹牛钙态,可吹牛的內(nèi)容都是我干的谷徙。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼驯绎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谋旦?” 一聲冷哼從身側(cè)響起剩失,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎册着,沒想到半個月后拴孤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡甲捏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年演熟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片司顿。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡芒粹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出大溜,到底是詐尸還是另有隱情化漆,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布钦奋,位于F島的核電站座云,受9級特大地震影響疙赠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜朦拖,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一圃阳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧璧帝,春花似錦捍岳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至理疙,卻和暖如春晕城,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背窖贤。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工砖顷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赃梧。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓滤蝠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親授嘀。 傳聞我的和親對象是個殘疾皇子物咳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容