我本來只想看看docker官方提供的CI/CD教程小泉,然后官方引用了脖捻,Ben's blog提到了CI/CD的最佳實踐愈诚,然后我就去閱讀了大神的博客荣堰,然后大神引用了另一個大神的通過docker開發(fā)你的Go程序的系列文章淹辞。OK医舆,我還挺喜歡這種引用的,那一層一層看吧象缀,肯定都是好內(nèi)容蔬将。
Chris大神說他剛開始加入開發(fā)團隊的時候,也遇到了很多編程語言央星,配置開發(fā)環(huán)境的問題霞怀,經(jīng)常需要問同事幫忙,還經(jīng)常被各種工具困擾莉给,這些過程非潮惺花費時間,并且他在維護debug CI過程的時候也非常痛苦颓遏。
他提到了一個角度我覺得很好徐矩,他說Go開發(fā)的工具鏈,提供快速編譯時間叁幢,內(nèi)置依賴管理滤灯,簡單的交叉編譯。但工具鏈會遇到諸多Go版本不匹配遥皂,缺少依賴力喷,配置不同的問題。一個很好的例子就是在許多項目中使用了gRPC演训,因此特定版本的protoc也很重要弟孟。
大神的博客涵蓋了構建,測試样悟,CI和優(yōu)化方案幫助大家更快上手拂募。
迎接究極干貨
從簡單的go程序開始:
package main
import "fmt"
func main() {
fmt.Println("Hello world!")
}
通過go build就可以編譯成二進制文件庭猩。
go build -o bin/example .
外加簡單的Dockerfile
FROM golang:1.14.3-alpine As build
WORKDIR /src
COPY . .
RUN go build -o /out/example .
FROM scratch AS bin
COPY --from=build /out/example /
說簡單也不簡單,兩階段構建陈症,第一階段蔼水,構建,用了Go Alpine鏡像录肯,Alpine鏡像大家了解吧趴腋,很多語言都有這個版本,超級輕量化论咏,常規(guī)機遇Debian的Golang輕量鏡像代替品优炬。定義了go的版本(我這個時候還在想,要不要做一個新版本的用例)厅贪。設置了工作目錄蠢护,將代碼復制到容器中,然后編譯养涮。第二階段使用了臨時的空鏡像(這個我頭次見)然后將第一階段的編譯好的耳機只文件復制到文件系統(tǒng)中葵硕。大神貼心的提到,如果我們的程序需要一些其他的資源比如CA證書贯吓,這些也需要包含在最終的鏡像中懈凹。
小tips:
我之前使用Alpine鏡像的時候,我們是不用跑docker run -it < image_id > bash的宣决,因為Alpine不帶蘸劈,那怎么進一個CLI呢?可以用/bin/sh尊沸。
升級版(交叉編譯版)
FROM --platform=${BUILDPLATFORM} golang:1.14.3-alpine AS build
WORKDIR /src
ENV CGO_ENABLED=0
COPY . .
ARG TARGETOS
ARG TARGETARCH
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /out/example .
FROM scratch AS bin
COPY --from=build /out/example /
使用了BUILDPLATFORM設置基礎鏡像平臺威沫。使用TARGETOS和TARGETARCH告訴Go在那個平臺構建。
大神還提供了Makefile洼专,makfile我還沒有學過多語法棒掠,一起看看吧
all: bin/example
.PHONY: bin/example
bin/example:
@docker build . --target bin --output bin/ --platform local
使用make,或者make bin/example都能構建屁商。
再進一步
FROM --platform=${BUILDPLATFORM} golang:1.14.3-alpine AS build
WORKDIR /src
ENV CGO_ENABLED=0
COPY . .
ARG TARGETOS
ARG TARGETARCH
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /out/example .
FROM scratch AS bin-unix
COPY --from=build /out/example /
FROM bin-unix AS bin-linux
FROM bin-unix AS bin-darwin
FROM scratch AS bin-windows
COPY --from=build /out/example /example.exe
FROM bin-${TARGETOS} AS bin
這已經(jīng)多階段方案了吧烟很,Linux(bin-linux),macOS(bin-darwin),windows(bin-windows)。我的天真希望我不要遇到這些問題蜡镶。這些可以讓我動態(tài)選擇編譯目標雾袱。
然后再優(yōu)化Makefile
all: bin/example
PLATFORM=local
.PHONY: bin/example
bin/example:
@docker build . --target bin --output bin/ --platform ${PLATFORM}
然后我們就可以指定使用平臺了
make PLATFORM=windows/amd64
makefile倆面的參數(shù)能這么直接傳真實學到了
還能學到一點
大神提到了使用.dcokerignore減少不需要的內(nèi)容,如果我們的項目通過git進行代碼管理官还,我覺得大多數(shù)的項目都是git管理吧芹橡,我們可以排出.git/目錄, 這一點再docker官網(wǎng)的教程了都沒寫。
reference
本文所有的例子都來自于大神的博客: https://www.docker.com/blog/containerize-your-go-developer-environment-part-1/