最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Docker多階段構(gòu)建鏡像multi-stage詳解

 更新時(shí)間:2025年10月24日 08:48:33   作者:尤達(dá)c  
多階段構(gòu)建是Docker 17.05及以上版本的新特性,允許在一個(gè)Dockerfile中使用多個(gè)階段,每個(gè)階段可以有一個(gè)獨(dú)立的基礎(chǔ)鏡像,并且可以通過(guò)COPY --from命令在階段之間傳遞文件,這樣可以有效地減少最終鏡像的大小,只保留必要的文件

多階段構(gòu)建是一個(gè)新特性,需要 Docker 17.05 或更高版本的守護(hù)進(jìn)程和客戶端。對(duì)于那些努力優(yōu)化 Dockerfiles 并使其易于閱讀和維護(hù)的人來(lái)說(shuō),多階段構(gòu)建非常有用。

在之前先來(lái)學(xué)習(xí)術(shù)語(yǔ):

  • multi-stage 多階段
  • build 構(gòu)建
  • image 鏡像
  • stage 階段

一、使用在多階段構(gòu)建之前

構(gòu)建鏡像時(shí)最具挑戰(zhàn)性的事情之一就是縮小鏡像大小。

Dockerfile 中的每一條指令都會(huì)在鏡像中添加一個(gè)層,在進(jìn)入下一層之前,您需要記住清除所有不需要的工件。

要編寫一個(gè)真正高效的 Dockerfile,傳統(tǒng)上需要使用 shell 技巧和其他邏輯來(lái)保持層盡可能小,并確保每一層都有它需要的來(lái)自前一層的工件,而沒有其他東西。

實(shí)際上,有一個(gè) Dockerfile 用于開發(fā)環(huán)境(包含構(gòu)建應(yīng)用程序所需的所有內(nèi)容,包括編譯工具等),同時(shí)有一個(gè)精簡(jiǎn)的 Dockerfile 用于生產(chǎn)環(huán)境(僅包含應(yīng)用程序和運(yùn)行應(yīng)用程序所需的內(nèi)容)是非常常見的。這被稱為“建造者模式”。維護(hù)兩個(gè) Dockerfiles 并不理想。

這里一個(gè)例子,對(duì)比一下 Dockerfile

優(yōu)化前 Dockerfile:

FROM openjdk:8u171-jdk-alpine3.8
 
ADD . /app
WORKDIR /app
 
RUN apk add maven \
  && mvn clean package \
  && apk del maven \
  && mv target/final.jar / \
  && cd / \
  && rm -rf /app \
  && rm -rf /root/.m2
 
ENTRYPOINT java -jar /final.jar

優(yōu)化后 Dockerfile:

FROM openjdk:8u171-jdk-alpine3.8 as builder
 
ADD . /app
WORKDIR /app
 
RUN apk add maven \
  && mvn clean package \
  && apk del maven \
  && mv target/final.jar /
 
FROM openjdk:8u181-jre-alpine3.8 as environment
WORKDIR /
COPY --from=builder /final.jar .
ENTRYPOINT java -jar /final.jar
  1. 很明顯,優(yōu)化后的 Dockerfile 新增了 FROM AS 這個(gè)命令,并出現(xiàn)了兩個(gè) FROM。這就是多階段構(gòu)建。
  2. 請(qǐng)注意,此示例還使用 Bash 操作符 && 將兩個(gè) RUN命令人為壓縮在一起,以避免在鏡像中創(chuàng)建額外的層。這很容易發(fā)生故障,也很難維護(hù)。例如,很容易插入另一個(gè)命令而忘記使用 \ 字符繼續(xù)行。

二、了解下多階段構(gòu)建

多階段構(gòu)建是 Docker 17.05 的新增功能,它可以在一個(gè) Dockerfile 中使用多個(gè) FROM 語(yǔ)句,以創(chuàng)建多個(gè) Stages(階段)。每個(gè)階段間獨(dú)立(來(lái)源請(qǐng)求),可以通過(guò) COPY --from 來(lái)獲取其它階段的文件

看看在 Dockerfile 中使用編譯工具構(gòu)建一個(gè) JAR,并只保留構(gòu)建完的 JAR 和運(yùn)行時(shí)交給 Image,其它則扔掉應(yīng)該怎么做:

# 第一階段——編譯
FROM openjdk:8u171-jdk-alpine3.8 as builder # 自帶編譯工具
ADD . /app
WORKDIR /app
RUN ... 省略編譯和清理工作...
 
 
# 現(xiàn)在,JAR 已經(jīng)出爐。JDK 不再需要,所以不能留在鏡像中。
# 所以我們開啟第二階段——運(yùn)行,并扔掉第一階段的所有文件(包括編譯工具)
# 第二階段——運(yùn)行
FROM openjdk:8u181-jre-alpine3.8 as environment # 只帶運(yùn)行時(shí)環(huán)境
 
# 目前,編譯工具等上一階段的東西已經(jīng)被我們拋下。目前的鏡像中只有運(yùn)行時(shí)環(huán)境,
# 我們需要把上一階段的結(jié)果拿來(lái),其它不要。
COPY --from=0 /final.jar .
 
# 好了,現(xiàn)在鏡像只有必要的運(yùn)行時(shí)和 JAR 了。
ENTRYPOINT java -jar /final.jar

如上就是多階段構(gòu)建的介紹

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

1. 只有最后一個(gè)stage才會(huì)被納入image中

多階段構(gòu)建的核心命令是 FROM。FORM 對(duì)于身經(jīng)百戰(zhàn)的你來(lái)說(shuō)已經(jīng)不用多講了。在多階段構(gòu)建中,每次 FROM 都會(huì)開啟一個(gè)新的 Stage(階段),可以看作一個(gè)新的 Image(不夠準(zhǔn)確、來(lái)源請(qǐng)求),與其它階段隔離(甚至包括環(huán)境變量)。只有最后的 FROM 才會(huì)被納入 Image 中。

我們來(lái)做一個(gè)最 simple 的多階段構(gòu)建例子:

# Stage 1
FROM alpine:3.8
WORKDIR /demo
RUN echo "Hello, stage 1" > /demo/hi-1.txt
 
# Stage 2
FROM alpine:3.8
WORKDIR /demo
RUN echo "Hello, stage 2" > /demo/hi-2.txt

可以自己構(gòu)建一下這個(gè) Dockerfile,然后 docker save > docker.tar

看看其中的內(nèi)容。不出意外應(yīng)該只有 /demo/hi-2.txt 和 Alpine。

在這個(gè) Dockerfile 中,我們創(chuàng)建了兩個(gè)階段。第一個(gè)階段創(chuàng)建 hi-1.txt,第二個(gè)階段創(chuàng)建 hi-2.txt,且第二個(gè)階段會(huì)被加入最終 Image,其它不會(huì)。

2. 復(fù)制文件——階段間的橋梁

如果階段間完全隔離,那么多階段就沒有意義——上一個(gè)階段的結(jié)果會(huì)被完全拋棄,并進(jìn)入全新的下一階段。

我們可以通過(guò) COPY 命令來(lái)獲取其它階段的文件。在多階段中使用 COPY 和普通應(yīng)用完全一致,僅需要添加 –form ` 即可。那么,我們修正上一個(gè)例子,使最終鏡像包含兩個(gè)階段的產(chǎn)物:

# Stage 1
FROM alpine:3.8
WORKDIR /demo
RUN echo "Hello, stage 1" > /demo/hi-1.txt
 
# Stage 2
FROM alpine:3.8
WORKDIR /demo
COPY --from=0 /demo/hi-1.txt /demo
RUN echo "Hello, stage 2" > /demo/hi-2.txt
  • 重新構(gòu)建并保存(Save),你會(huì)發(fā)現(xiàn)多了一層 Layer,其中包含 hi-1.txt。
  • 第二個(gè) FROM 指令用 alpine:3.8 鏡像作為基礎(chǔ),開始一個(gè)新的構(gòu)建階段。
  • COPY --from=0 行只將前一階段的構(gòu)建工件復(fù)制到這個(gè)新階段;
  • FROM 指令的第一個(gè)整數(shù)從 0 開始,0代表第一階段

3. 階段命名——快速識(shí)別

每次使用 stage index 并不是一件很妙的事情。

這時(shí)候,可以通過(guò)階段命名的方式給它們賦予名字,以方便識(shí)別。

為階段添加名字很簡(jiǎn)單,只需要在 FROM 后加上 as 即可。

現(xiàn)在,我們更新 Dockerfile,給予階段名稱并使用名稱來(lái) COPY。

# Stage 1, it's name is "build1"
FROM alpine:3.8 as build1
WORKDIR /demo
RUN echo "Hello, stage 1" > /demo/hi-1.txt
 
# Stage 2, it's name is "build2"
FROM alpine:3.8 as build2
WORKDIR /demo
# No longer use indexes
COPY --from=build1 /demo/hi-1.txt /demo
RUN echo "Hello, stage 2" > /demo/hi-2.txt

重新構(gòu)建并保存,結(jié)果應(yīng)該同上次相同。

4. 僅構(gòu)建其中的部分階段——輕松調(diào)試

Docker 還為我們提供了一個(gè)很方便的調(diào)試方式——僅構(gòu)建部分階段。它可以使構(gòu)建停在某個(gè)階段,并不構(gòu)建后面的階段。這可以方便我們調(diào)試;區(qū)分生產(chǎn)、開發(fā)和測(cè)試。

仍然沿用上次的 Dockerfile,但使用 --target 參數(shù)進(jìn)行構(gòu)建:

$ docker build --target build1 .

再次 Save,你會(huì)發(fā)現(xiàn)只有 build1 的內(nèi)容。

總結(jié)

這就是一些多階段構(gòu)建的用法

很顯然,利用多階段無(wú)需包含無(wú)用的 JDK,JDK 只在編譯時(shí)起作用,編譯完便無(wú)用了,只需要 JRE 即可。所以,利用多階段構(gòu)建可以隔離編譯階段和運(yùn)行階段,以達(dá)到鏡像最優(yōu)化。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決docker的tls(ssl)證書過(guò)期問題

    解決docker的tls(ssl)證書過(guò)期問題

    這篇文章主要介紹了解決docker的tls(ssl)證書過(guò)期問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03
  • Windows docker的安裝和初使用詳細(xì)教程

    Windows docker的安裝和初使用詳細(xì)教程

    Docker是開源容器引擎,用于打包應(yīng)用及依賴,安裝需Windows10/11專業(yè)版/企業(yè)版,啟用WSL2和Hyper-V,配置鏡像和端口映射,支持本地文件掛載,卸載時(shí)關(guān)閉DockerDesktop并重啟系統(tǒng),本文給大家介紹Windows docker的安裝和初使用,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • 一文搞定Docker安裝ElasticSearch的過(guò)程

    一文搞定Docker安裝ElasticSearch的過(guò)程

    通過(guò)本文可以幫助大家快速學(xué)習(xí)Docker安裝ElasticSearch的過(guò)程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-08-08
  • docker自定義網(wǎng)橋docker0及docker的開啟,關(guān)閉,重啟命令操作

    docker自定義網(wǎng)橋docker0及docker的開啟,關(guān)閉,重啟命令操作

    這篇文章主要介紹了docker自定義網(wǎng)橋docker0及docker的開啟,關(guān)閉,重啟命令操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03
  • 編寫最佳的Dockerfile的方法

    編寫最佳的Dockerfile的方法

    本文給大家分享的是如何編寫最佳的dockerfile的方法,通過(guò)具體實(shí)例幫助大家快速掌握編寫Dockerfile的技巧
    2017-06-06
  • Docker構(gòu)建鏡像的三大優(yōu)化方法指南

    Docker構(gòu)建鏡像的三大優(yōu)化方法指南

    這篇文章主要為大家詳細(xì)介紹了Docker構(gòu)建鏡像的三大優(yōu)化方法,包括CMD/ENTRYPOINT、多階段構(gòu)建與緩存優(yōu)化,下面就跟隨小編一起深入了解下吧
    2025-11-11
  • Docker 中 Crontab 不執(zhí)行的原因全解析與解決方案

    Docker 中 Crontab 不執(zhí)行的原因全解析與解決方案

    文章總結(jié)了在Docker容器里使用crontab時(shí)遇到的問題及解決方法,常見問題包括缺少cron服務(wù)、服務(wù)未啟動(dòng)、容器銷毀后任務(wù)丟失等,解決方法包括使用Supervisor管理cron、將任務(wù)放在宿主機(jī)的crontab、通過(guò)掛載方式加載宿主機(jī)的cron文件,感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • 使用Docker構(gòu)建企業(yè)級(jí)自定義鏡像的方法

    使用Docker構(gòu)建企業(yè)級(jí)自定義鏡像的方法

    這篇文章主要介紹了使用Docker構(gòu)建企業(yè)級(jí)自定義鏡像的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Docker連接宿主Redis的方法步驟

    Docker連接宿主Redis的方法步驟

    本文主要介紹了Docker連接宿主Redis的方法步驟,可以輕松地使用Docker容器與宿主機(jī)上的Redis進(jìn)行交互,實(shí)現(xiàn)高效的數(shù)據(jù)存儲(chǔ)和共享,,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • Docker實(shí)現(xiàn)鏡像優(yōu)化的實(shí)用技巧分享

    Docker實(shí)現(xiàn)鏡像優(yōu)化的實(shí)用技巧分享

    鏡像太大、構(gòu)建太慢、上傳半天,這時(shí)是時(shí)候掌握一些真正實(shí)用的?Docker?鏡像優(yōu)化技巧了,下面小編就帶大家從實(shí)踐角度出發(fā),逐步優(yōu)化鏡像體積,構(gòu)建速度與運(yùn)行性能吧
    2026-04-04

最新評(píng)論

恩施市| 盐亭县| 灵璧县| 河津市| 体育| 霍林郭勒市| 宁海县| 丹凤县| 肃南| 个旧市| 龙岩市| 隆林| 灵台县| 同心县| 阿瓦提县| 瓦房店市| 湟中县| 临海市| 呼和浩特市| 华池县| 盐山县| 诸暨市| 雅安市| 景宁| 渭南市| 邓州市| 广水市| 宁阳县| 岑溪市| 张北县| 磐安县| 永年县| 黄龙县| 迁西县| 涞源县| 历史| 丹东市| 华亭县| 麻栗坡县| 千阳县| 剑河县|