深入解析Multi-stage構建多階段鏡像

一、Multi-stage概述

Multi-stage是Docker自17.05版本引入的新特性。它允許在一個Dockerfile中定義多個鏡像構建階段,並針對當前階段選擇不同的基礎鏡像,從而減小鏡像大小,提高構建效率。

Multi-stage的實現依賴於Docker buildkit,可以通過設置DOCKER_BUILDKIT環境變數來啟用。另外需要注意的是,Multi-stage對鏡像的命名並無強制要求,可以根據需求任意命名。

二、基礎用法

Multi-stage最基礎的用法就是使用多個FROM語句定義多個階段,比如以下例子:

FROM golang:1.15 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine
COPY --from=builder /app/app .
CMD ["./app"]

這個Dockerfile定義了兩個階段,第一個階段使用golang:1.15鏡像作為基礎鏡像,將當前目錄下的所有文件複製到/app目錄下,然後使用go build構建應用程序。第二個階段使用alpine鏡像作為基礎鏡像,只包含Glibc運行庫和基礎命令,將第一個階段構建的應用程序複製到當前目錄,並設置啟動命令為”./app”。

三、多階段鏈式調用

Multi-stage還可以鏈式調用,將一個階段的輸出作為下一個階段的輸入,從而實現更複雜的構建過程。下面是一個簡單的例子:

FROM golang:1.15 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM scratch
COPY --from=builder /app/app .
ENTRYPOINT ["/app"]

這個Dockerfile定義了兩個階段,第一個階段與之前的例子相同,第二個階段使用scratch空鏡像作為基礎鏡像,意味著只包含一個空白文件系統。將第一個階段構建的應用程序複製到當前目錄下,設置啟動命令為”/app”。

四、減少鏡像大小

Multi-stage可以幫助我們減小鏡像大小,在構建應用程序的時候只保留必要的文件和運行時依賴庫,避免不必要的文件和依賴導致鏡像體積過大。

以Node.js應用為例,我們可以只保留應用程序和運行所需的依賴庫,而不包含npm包管理器和應用的開發依賴庫。下面是一個示例Dockerfile:

FROM node:14.16 AS build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM node:14.16-alpine
WORKDIR /app
COPY --from=build-stage /app/dist ./dist
COPY package*.json ./
RUN npm install --production
CMD ["npm", "run", "start"]

這個Dockerfile定義了兩個階段,第一個階段使用node:14.16鏡像作為基礎鏡像,安裝應用程序的開發依賴庫,構建應用程序。第二個階段使用node:14.16-alpine鏡像作為基礎鏡像,只包含Node.js運行時依賴庫和基礎命令,將第一個階段構建的應用程序複製到當前目錄下的dist目錄,並安裝生產依賴庫,設置啟動命令為”npm run start”。

五、交叉編譯

Multi-stage還可以用於交叉編譯應用程序,比如將應用程序編譯為不同平台的二進位文件。下面是一個簡單的例子:

FROM golang:1.15 AS builder
WORKDIR /app
COPY . .
RUN GOOS=linux GOARCH=amd64 go build -o app-linux-amd64 .
RUN GOOS=windows GOARCH=amd64 go build -o app-windows-amd64.exe .

FROM scratch
COPY --from=builder /app/app-linux-amd64 .
ENTRYPOINT ["/app-linux-amd64"]

這個Dockerfile定義了兩個階段,第一個階段使用golang:1.15鏡像作為基礎鏡像,將當前目錄下的所有文件複製到/app目錄下,分別使用GOOS和GOARCH環境變數交叉編譯應用程序為Linux和Windows平台,輸出兩個二進位文件。

六、小結

Multi-stage是Docker非常實用的一個特性,可以幫助我們優化Docker鏡像構建過程、減小鏡像大小、提高構建效率。通過本文介紹的幾個例子,相信大家已經掌握了Multi-stage的基礎用法及更多高級用法,希望可以對大家的Docker實踐有所幫助。

原創文章,作者:RXSLR,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/363836.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
RXSLR的頭像RXSLR
上一篇 2025-03-12 18:48
下一篇 2025-03-12 18:48

相關推薦

  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29
  • 現在鏡像站不行了,怎麼辦?

    現在鏡像站不行了是很常見的問題,本文將從多個方面對此問題進行詳細闡述,為大家提供解決方案。 一、檢查網路環境 鏡像站不通常見的原因之一是網路問題,可能是個人網路不穩定,也可能是IS…

    編程 2025-04-29
  • 如何在Python中配置國內鏡像源

    如果你使用Python進行開發,那麼肯定會遇到下載模塊或庫速度慢的情況。這時,我們就可以配置國內鏡像源來解決這一問題。本文將會從多個方面來介紹如何配置國內鏡像源。 一、pip配置國…

    編程 2025-04-27
  • 深入解析Vue3 defineExpose

    Vue 3在開發過程中引入了新的API `defineExpose`。在以前的版本中,我們經常使用 `$attrs` 和` $listeners` 實現父組件與子組件之間的通信,但…

    編程 2025-04-25
  • 深入理解byte轉int

    一、位元組與比特 在討論byte轉int之前,我們需要了解位元組和比特的概念。位元組是計算機存儲單位的一種,通常表示8個比特(bit),即1位元組=8比特。比特是計算機中最小的數據單位,是…

    編程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什麼是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一個內置小部件,它可以監測數據流(Stream)中數據的變…

    編程 2025-04-25
  • 深入探討OpenCV版本

    OpenCV是一個用於計算機視覺應用程序的開源庫。它是由英特爾公司創建的,現已由Willow Garage管理。OpenCV旨在提供一個易於使用的計算機視覺和機器學習基礎架構,以實…

    編程 2025-04-25
  • 深入了解scala-maven-plugin

    一、簡介 Scala-maven-plugin 是一個創造和管理 Scala 項目的maven插件,它可以自動生成基本項目結構、依賴配置、Scala文件等。使用它可以使我們專註於代…

    編程 2025-04-25
  • 深入了解LaTeX的腳註(latexfootnote)

    一、基本介紹 LaTeX作為一種排版軟體,具有各種各樣的功能,其中腳註(footnote)是一個十分重要的功能之一。在LaTeX中,腳註是用命令latexfootnote來實現的。…

    編程 2025-04-25
  • Docker鏡像管理

    一、查看所有鏡像 使用docker命令可以很輕鬆地查看所有已經構建好的鏡像,命令如下: docker images 該命令將列出所有本地docker主機上所有的鏡像: REPOSI…

    編程 2025-04-25

發表回復

登錄後才能評論