首先Go自己在交叉編譯方法十分強大,這裏就再也不贅述了,有須要的同窗能夠參考《Golang交叉編譯各個平臺的二進制文件》。雖然自帶的交叉編譯已足夠強大,而且能知足大部分的使用場景,但仍是有一個坑人的地方就是當源代碼中包含CGO代碼時,默認交叉編譯就會出錯,具體能夠參考《CGO_ENABLED環境變量對Go靜態編譯機制的影響》。實際上有一種能夠一勞永逸地解決,並保證線下編譯與線上部署環境一致的項目構建方法,那就是基於Docker的「交叉編譯方案」。html
Docker是近年來十分流行的Linux容器化技術,相比傳統的虛擬機技術,其佔用的系統資源更小,體積小,啓動速度也很是迅捷。同時Docker已經能在主流操做系統Windows, macOS和Linux上獲得快速的構建,這一點對本文接下來要講的交叉編譯十分重要。有關容器的詳細介紹具體可參考docker入門教程,其安裝方法也很是簡單。git
爲了保證一次編譯,處處運行的效果(有點相似JAVA虛擬機),所以須要採用同一個Docker基礎鏡像分別用於代碼編譯和部署的工做,本文基於DockerHub官方發佈的golang:1.14.3-stretch定製了一個鏡像,該鏡像更加方便對項目代碼的編譯導出,鏡像體積大概在280MB左右,比較能使人接受。下面是鏡像的Dockerfile:golang
FROM golang:1.14.3-stretch
MAINTAINER author <email@xxx.com>
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
wget \
vim \
htop \
curl \
sudo \
git \
net-tools \
tzdata \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& rm -rf /var/lib/apt/lists/*
ENV GOBIN=$GOPATH/bin
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.io,direct
ENV TZ=Asia/Shanghai
WORKDIR $GOPATH/src/app
ENTRYPOINT ["go", "build"]
複製代碼
p.s. 以上鏡像的Golang環境默認開啓GOMODULE模式,所以爲保證能順利編譯,項目須要初始化go.mod
docker
有了上面的Dockerfile
,而後咱們就能迅速地構建鏡像並實例化相應的容器,從而完成對項目源代碼的編譯和部署工做,具體步驟以下:vim
# 在Dockerfile所處當前目錄下,執行
~$ docker build -t gobuilder:1.14.3-stretch .
複製代碼
# 假設你的項目目錄gosrc包含如下文件:
/abspath/gosrc
|---package
| |---func1.go
| |---func2.go
|---go.mod
|---config.yml
|---main.go
# 運行如下容器編譯你的go項目並導出可執行文件到當前目錄下
~$ docker run --rm -it -v /abspath/gosrc/:/go/src/app gobuilder
複製代碼
在這裏,直接運行go項目有兩種方法:
第一種是像剛纔介紹的那樣,先編譯後執行導出的可執行文件就可運行你的應用。若是是線上部署,一樣能夠在鏡像gobuilder
能夠專門給你的main
可執行文件編寫特定的Dockerfile
用於應用鏡像的構建和實例化,具體能夠參考如下的構建方法:app
FROM gobuilder:1.14.3-stretch
MAINTAINER author <email@xxx.com>
WORKDIR /app
COPY . .
RUN chmod 777 main
# master process
ENTRYPOINT ["./main"]
複製代碼
第二種是採用go run
的形式直接運行你的go文件,開啓應用進程,一樣是基於gobuilder
鏡像,啓動時只要掛載項目並修改ENTRYPOINT
和CMD
參數便可,具體參考以下命令:curl
# 若是須要容器應用後臺運行,只需將-it改爲-d便可
~$ docker run --name YourAppName -it -v /abspath/gosrc/:/go/src/app --entrypoint go gobuilder run main.go
複製代碼
本文主要介紹了一種基於Docker
編譯並運行應用的方法,該方法能夠在任何(Linux
, macOS
和Windows
)安裝有Docker
環境的機器上作到一致性部署。能達到一次編譯,處處運行的效果,這一點卻是很像JAVA
的虛擬機,有殊途同歸之妙。經過拉取鏡像並實例化容器的方式,同時也能避免每次在新機器上搭建運行時環境的苦惱。本人小白一枚,還在不斷學習中,所以如有錯誤和疏漏的地方,還望指正,謝謝!學習