1. 程式人生 > >go專案dockerfile最佳實踐

go專案dockerfile最佳實踐

- [1. 前言](#head1) - [2. 不需要cgo情況下的最佳實踐](#head2) - [3. 依賴cgo情況下的最佳實踐](#head3) # 1. 前言 這幾天在構建golang編寫的web專案中,關於dockerfile編寫的一些總結 > 可能是單純我比較菜(大霧 由於go應用在`go build`之後會生成一個二進位制檔案,且Go宣稱自己只需要Linux核心 > 大多數程式語言都依賴於直譯器,VM和/或系統庫 剛開始我按照常理思考,寫出瞭如下的`dockerfile`, **但是最終`docker build`出來的映象高達300多M**, 這是由於`golang`這個基礎映象中的工具鏈及其依賴項(`git`,`mercurial`等)重達幾百MB,而這一部分我們在執行的時候是不需要的 ```dockerfile FROM golang:1.14 ENV GO111MODULE=on \ GOPROXY=https://goproxy.cn,direct \ GIN_MODE=release \ PORT=80 WORKDIR /app COPY . . RUN go build . EXPOSE 80 ENTRYPOINT ["./toc-generator"] ``` # 2. 不需要cgo情況下的最佳實踐 docker有一個基本映象叫做scratch,它是一個空的映象,在臨時基礎映象上執行的應用程式只能訪問核心 > 至少在容器提供隔離的範圍內 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gh852yo5clj314z0phadx.jpg) **所以此時我們的思路是** 1. 在`golang`基礎映象下build出二進位制檔案 2. 然後使用`scratch`作為執行時的基礎映象 3. 並且將上一個stage build出來的`二進位制檔案`和`它的相關依賴檔案`copy到scratch下 所以我們現在的`dockerfile`大概如下 ```dockerfile # 打包依賴階段使用golang作為基礎映象 FROM golang:1.14 as builder # 啟用go module ENV GO111MODULE=on \ GOPROXY=https://goproxy.cn,direct WORKDIR /app COPY . . # CGO_ENABLED禁用cgo 然後指定OS等,並go build RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build . # 由於我不止依賴二進位制檔案,還依賴views資料夾下的html檔案還有assets資料夾下的一些靜態檔案 # 所以我將這些檔案放到了publish資料夾 RUN mkdir publish && cp toc-generator publish && \ cp -r views publish && cp -r assets publish # 執行階段指定scratch作為基礎映象 FROM scratch WORKDIR /app # 將上一個階段publish資料夾下的所有檔案複製進來 COPY --from=builder /app/publish . # 為了防止程式碼中請求https連結報錯,我們需要將證書納入到scratch中 COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/cert # 指定執行時環境變數 ENV GIN_MODE=release \ PORT=80 EXPOSE 80 ENTRYPOINT ["./toc-generator"] ``` # 3. 依賴cgo情況下的最佳實踐 由於需要依賴cgo,所以我們使用`scratch`無法滿足需求,我們需要另外一個執行時基礎映象`alpine`,看下`dockerhub`官方的介紹,它也僅僅只有5MB大小 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gh85id5eopj31590djmym.jpg) 所以替換下基礎映象,我們的`dockerfile`變成了如下的樣子: ```dockerfile # 打包依賴階段使用golang作為基礎映象 FROM golang:1.14 as builder # 啟用go module ENV GO111MODULE=on \ GOPROXY=https://goproxy.cn,direct WORKDIR /app COPY . . # 指定OS等,並go build RUN GOOS=linux GOARCH=amd64 go build . # 由於我不止依賴二進位制檔案,還依賴views資料夾下的html檔案還有assets資料夾下的一些靜態檔案 # 所以我將這些檔案放到了publish資料夾 RUN mkdir publish && cp toc-generator publish && \ cp -r views publish && cp -r assets publish # 執行階段指定scratch作為基礎映象 FROM alpine WORKDIR /app # 將上一個階段publish資料夾下的所有檔案複製進來 COPY --from=builder /app/publish . # 指定執行時環境變數 ENV GIN_MODE=release \ PORT=80 EXPOSE 80 ENTRYPOINT ["./toc-generator"] ``` **參考連結** > https://baijiahao.baidu.com/s?id=1617163590078677512&wfr=spider