基於Docker的Golang交叉編譯

前言

首先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.moddocker

如何使用

有了上面的Dockerfile,而後咱們就能迅速地構建鏡像並實例化相應的容器,從而完成對項目源代碼的編譯和部署工做,具體步驟以下:vim

1. 構建鏡像
# 在Dockerfile所處當前目錄下,執行
    ~$ docker build -t gobuilder:1.14.3-stretch .
複製代碼
2. 編譯你的項目go源碼
# 假設你的項目目錄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
複製代碼
3. 運行你的go項目

在這裏,直接運行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鏡像,啓動時只要掛載項目並修改ENTRYPOINTCMD參數便可,具體參考以下命令:curl

# 若是須要容器應用後臺運行,只需將-it改爲-d便可
~$ docker run --name YourAppName -it -v /abspath/gosrc/:/go/src/app --entrypoint go gobuilder run main.go
複製代碼

總結

本文主要介紹了一種基於Docker編譯並運行應用的方法,該方法能夠在任何(Linux, macOSWindows)安裝有Docker環境的機器上作到一致性部署。能達到一次編譯,處處運行的效果,這一點卻是很像JAVA的虛擬機,有殊途同歸之妙。經過拉取鏡像並實例化容器的方式,同時也能避免每次在新機器上搭建運行時環境的苦惱。本人小白一枚,還在不斷學習中,所以如有錯誤和疏漏的地方,還望指正,謝謝!學習

相關文章
相關標籤/搜索