一、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