本文地址:https://www.cnblogs.com/likeli/p/10521941.html
喜大奔的go mod
官方背書的go mod拯救了我的代碼潔癖症!
環境
- go v1.12
- docker ce 18.09.0
- gitlab ce latest
godep
寫go程序,若是僅僅是你一個人寫,或者就是寫個小工具玩兒玩兒,依賴管理對你來說可能沒那么重要。
但是在商業的工程項目里,多人協同,go的依賴管理就尤為重要了,之前可選的其實不太多,社區提供的實現方式大多差不多的思路,比如我之前使用的godep。所以項目中會有一個vendor文件夾來存放外部的依賴,這樣:

這樣的實現方式,每次更新了外部依賴,其他人就得拉下來一大坨。。。
go mod
來看看使用官方的module來管理依賴的工程結構:

是不是,清爽無比,項目也整個瘦身了!
簡單的說一下go mod help,至於開啟go mod的步驟,其他網文一大堆,就不復制了。畢竟本文是說go工程CI/CD的。
在目前go v1.12版本下,命令go mod help結果如下:
The commands are:
download download modules to local cache
edit edit go.mod from tools or scripts
graph print module requirement graph
init initialize new module in current directory
tidy add missing and remove unused modules
vendor make vendored copy of dependencies
verify verify dependencies have expected content
why explain why packages or modules are needed
后面CI/CD需要用到的是download指令。
dockerfile
來看看我這個工程的dockerfile:
FROM golang:1.12 as build
ENV GOPROXY https://go.likeli.top
ENV GO111MODULE on
WORKDIR /go/cache
ADD go.mod .
ADD go.sum .
RUN go mod download
WORKDIR /go/release
ADD . .
RUN GOOS=linux CGO_ENABLED=0 go build -ldflags="-s -w" -installsuffix cgo -o app main.go
FROM scratch as prod
COPY --from=build /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=build /go/release/app /
COPY --from=build /go/release/conf.yaml /
CMD ["/app"]
我這個項目有一些外部依賴,在本地開發的時候都已調整好,並且編譯通過,在本地開發環境已經生成了兩個文件go.mod、go.sum
在dockerfile的第一步驟中,先啟動module模式,且配置代理,因為有些牆外的包服務沒有梯子的情況下也是無法下載回來的,這里的代理域名是我自己的,有需要的也可以用。
指令RUN go mod download執行的時候,會構建一層緩存,包含了該項所有的依賴。之后再次提交的代碼中,若是go.mod、go.sum沒有變化,就會直接使用該緩存,起到加速構建的作用,也不用重復的去外網下載依賴了。若是這兩個文件發生了變化,就會重新構建這個緩存分層。
使用緩存構建的效果:

這個加速效果是很明顯的。
減小體積
go構建命令使用-ldflags="-s -w"
在官方文檔:Command_Line里面說名了-s -w參數的意義,按需選擇即可。
-s: 省略符號表和調試信息-w: 省略DWARF符號表

看起來效果不錯🙂
使用scratch鏡像
使用golang:1.12開發鏡像構建好應用后,在使用scratch來包裹生成二進制程序。
關於最小基礎鏡像,docker里面有這幾類:
- scratch: 空的基礎鏡像,最小的基礎鏡像
- busybox: 帶一些常用的工具,方便調試, 以及它的一些擴展busybox:glibc
- alpine: 另一個常用的基礎鏡像,帶包管理功能,方便下載其它依賴的包
鏡像瘦身最終效果
好了,看看最終構建的應用的效果:

構建的鏡像大小為: 16.4MB
CI/CD
基於gitlab的runner來進行CI/CD,看看我的.gitlab-ci.yml配置:
before_script:
- if [[ $(whereis docker-compose | wc -l) -eq 0 ]]; then curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose; fi
# ******************************************************************************************************
# ************************************** 測試環境配置 ****************************************************
# ******************************************************************************************************
deploy-test-tour:
stage: deploy
tags:
- build
only:
- release/v2.0
script:
- export PRODUCTION=false
- docker-compose stop
- docker-compose up -d --build
# ******************************************************************************************************
# ************************************** 生產環境配置 ****************************************************
# ******************************************************************************************************
deploy-prod-tour:
stage: deploy
tags:
- release
only:
- master
script:
- export PRODUCTION=true
- docker-compose stop
- docker-compose up -d --build
我使用docker-compose來進行容器控制,所以在before_script過程里面增加了這一步,方便新機器的全自動化嘛。
我這個項目做了點兒工程化,所以稍微正規點兒,分出了兩個環境,測試和生產環境。分別綁定到不同的分支上。
正主就是下面執行的這三行:
export PRODUCTION=false
docker-compose stop
docker-compose up -d --build
export控制一下臨時環境變量,方便發布不同的環境。docker-compose stop停止舊的容器docker-compose up -d --build編排新的容器並啟動,會使用之前的緩存分層鏡像,所以除了第一次構建,后面的速度都是杠杠的。
看實際的發布截圖:

首次執行,總共:1 minute 22 seconds

使用緩存構建,總共:33 seconds
