簡介
很多時(shí)候我們本地開發(fā)環(huán)境和線上環(huán)境是不一致的,比如mac開發(fā)杏慰,linux運(yùn)行留储。通常的做法如下:
本地開發(fā)->上傳git->服務(wù)器拉取代碼->編譯->運(yùn)行
時(shí)間久了會發(fā)現(xiàn)七嫌,這樣非常麻煩惩激。
一種更好的方式是使用docker構(gòu)建本地編譯環(huán)境港准,可以非常方便的編譯適合各個(gè)平臺的程序版本
原理
原理很簡單,就是利用官方提供的golang鏡像咧欣,將本地的代碼通過掛載的方式,掛載到容器中轨帜,然后再容器中編譯即可魄咕。
golang開發(fā)環(huán)境的鏡像我們這里選擇golang:1.8(也可以選擇其他的鏡像),這個(gè)鏡像的目錄結(jié)構(gòu)為:
/go/bin
/go/src
他的gopath 為 /go
可以通過以下命令查看:
docker run --rm golang:1.8 go env
具體可以參考官方dockerfile文件蚌父,搜索gopath即可哮兰。
https://github.com/docker-library/golang/blob/9bf6daddb324a4d8e82b0613cf348a6eff363f95/1.10/stretch/Dockerfile
因此,我們可以將本地的gopath映射到容器的/go目錄(這樣我們項(xiàng)目依賴的go包也會自動掛載到容器的gopath目錄下)
將要編譯的本地程序映射到容器的/go/src/myapp 目錄下苟弛,然后執(zhí)行編譯即可喝滞。
舉例
一條命令就可以搞定:
docker run -v "$GOPATH":/go --rm -v "$PWD":/go/src/myapp -w /go/src/myapp -e GOOS="darwin" -e GOARCH="amd64" golang:1.8 go build -v
解釋下這句話的意思:
--rm :會在每次執(zhí)行完編譯后自動刪除容器(不加這個(gè)參數(shù),使用docker ps -a會看到我們上一次執(zhí)行結(jié)束的容器)
-v "$GOPATH":/go:將本地gopath映射到容器中膏秫,這樣容器中就不會提示缺少包
-v "$PWD":/go/src/myapp:將本地代碼映射到容器中右遭,本地代碼目錄為myapp
-e GOOS/-e GOARCH:指定編譯平臺,可以很方便的進(jìn)行交叉編譯
golang:1.8:鏡像名稱
這樣,我們只需要在我們的代碼目錄下窘哈,增加一個(gè)腳本build.sh, 內(nèi)容如下:
docker run -v "$GOPATH":/go --rm -v "$PWD":/go/src/myapp -w /go/src/myapp -e GOOS="darwin" -e GOARCH="amd64" golang:1.8 go build -v
可以根據(jù)需求吹榴,自己修改這個(gè)腳本。
然后再需要編譯的時(shí)候滚婉,直接執(zhí)行這個(gè)腳本就會在本地目錄下生成編譯好的二進(jìn)制文件图筹,非常方便
疑問
golang對交叉編譯支持的很好,最簡單的方式如下:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
不過對于某些項(xiàng)目让腹,直接本地交叉編譯經(jīng)常報(bào)錯(cuò)远剩,報(bào)錯(cuò)原因沒有深究。還是采用本文所述方法骇窍,保持程序運(yùn)行環(huán)境和編譯環(huán)境一致最穩(wěn)妥瓜晤。