iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 25
0
Modern Web

BeeGo系列 第 25

Docker - MultiStage

前幾篇我們介紹過怎麼打包成 Docker image,但是今天看了一下,發現 image 大小居然超過 500 MB,明明檔案不大,可是 image 大小卻這麼大,嗯,是該來最佳化一下。

分析

首先我們要先做分析,我們可以使用 dive 這個工具來做分析,看到底是哪個步驟產出了大量的檔案。

安裝 dive 非常簡單,兩行就搞定了。

wget https://github.com/wagoodman/dive/releases/download/v0.8.1/dive_0.8.1_linux_amd64.deb
sudo dpkg -i dive_0.8.1_linux_amd64.deb

然後執行 dive ,就可以看到分析的結果,按上或下方向鍵,可以察看每個步驟的影響 (按 ctrl+c 可以離開)。
https://ithelp.ithome.com.tw/upload/images/20191004/20012434FnxNuXVRPF.png
從執行的結果來看,整個 image 大小是 519MB,我們可以發現光是選用的 golang:1.13-alpine 就用掉 353 MB,之後安裝 go 的 std library 佔用了 98MB,beego 應用程式的原始碼以及建置後的結果,則佔用了 30MB。

對策

已經知道哪幾個步驟比較有問題之後,就可以來一一處理了。

首先,Docker 最近有提出 Multi-Stage build,這可以避免處理肥大的建置環境問題。

我們對 Dockerfile 做調整,第一個是加了 base,當作最終結果的基礎

#
# base
#
FROM alpine:3.10 AS base
RUN apk add --no-cache curl wget

再來,之前分析的結果,建置所需的函式庫佔了三百多 MB。我們仍然要建置 (從 # builder 該行開始到 # final ),但是只要建置後的結果,所以在 final 那層 ( # final 該行之後),就只有複製 builder 層的結果過來到 base。

#
# builder,只為了建置而使用
#
FROM golang:1.13-alpine3.10 AS builder

# git
RUN apk add --no-cache git

# Recompile the standard library without CGO
RUN CGO_ENABLED=0 go install -a std

ENV APP_DIR /app
RUN mkdir -p $APP_DIR

# Set the entrypoint
ADD . $APP_DIR

# Compile the binary and statically link
RUN cd $APP_DIR && CGO_ENABLED=0 go build -ldflags '-d -w -s'

#
# final
#
FROM base AS final

ENV APP_DIR /app
RUN mkdir -p $APP_DIR
# 只複製我們需要的部份
COPY --from=builder /app/ithome-iron-beego $APP_DIR/ithome-iron-beego
COPY --from=builder /app/conf $APP_DIR/conf
COPY --from=builder /app/views $APP_DIR/views

ENTRYPOINT (cd $APP_DIR && ./ithome-iron-beego)
EXPOSE 8080

改完 Dockerfile 以後,重新建置看看

docker build -t elleryq/ithome-iron-beego:0.2.0 .

# p.s. 也可以用 dive 來 build,build 完後會直接帶出分析結果
dive build -t elleryq/ithome-iron-beego:0.2.0 .

分析的結果
https://ithelp.ithome.com.tw/upload/images/20191004/20012434T2NrGZtQWb.png
我們可以看到,整個 image 大小變成只有 19MB 了。

這次只有改 Dockerfile 而已,完整的程式碼可以參考 Github

參考資料


上一篇
自動產出API文件
下一篇
佈署
系列文
BeeGo30

尚未有邦友留言

立即登入留言