基於Docker的Golang交叉編譯


基於Docker的Golang交叉編譯

引用了一篇不錯的文章

前言

首先Go本身在交叉編譯方法十分強大,這里就不再贅述了,有需要的同學可以參考《Golang交叉編譯各個平台的二進制文件》。雖然自帶的交叉編譯已足夠強大,並且能滿足大部分的使用場景,但還是有一個坑人的地方就是當源代碼中包含CGO代碼時,默認交叉編譯就會出錯,具體可以參考《CGO_ENABLED環境變量對Go靜態編譯機制的影響》。實際上有一種可以一勞永逸地解決,並保證線下編譯與線上部署環境一致的項目構建方法,那就是基於Docker的“交叉編譯方案”。

Docker是近年來十分流行的Linux容器化技術,相比傳統的虛擬機技術,其占用的系統資源更小,體積小,啟動速度也非常迅捷。同時Docker已經能在主流操作系統Windows, macOS和Linux上得到快速的構建,這一點對本文接下來要講的交叉編譯十分重要。有關容器的詳細介紹具體可參考docker入門教程,其安裝方法也非常簡單。

方法

准備一個基礎鏡像

為了保證一次編譯,到處運行的效果(有點類似JAVA虛擬機),因此需要采用同一個Docker基礎鏡像分別用於代碼編譯和部署的工作,本文基於DockerHub官方發布的golang:1.14.3-stretch定制了一個鏡像,該鏡像更加方便對項目代碼的編譯導出,鏡像體積大概在280MB左右,比較能令人接受。下面是鏡像的Dockerfile:

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

如何使用

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

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用於應用鏡像的構建和實例化,具體可以參考以下的構建方法:

    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參數即可,具體參考如下命令:

# 如果需要容器應用后台運行,只需將-it改成-d即可
~$ docker run --name YourAppName -it -v /abspath/gosrc/:/go/src/app --entrypoint go gobuilder run main.go
復制代碼

總結

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM