preface

First of all, Go itself is very powerful in the cross-compilation method, which will not be described here. If you need it, you can refer to the “Golang cross-compilation binaries for various platforms”. Although the built-in cross-compilation is powerful enough for most use scenarios, one catch is that cross-compilation fails by default when CGO code is included in the source code, as described in the CGO_ENABLED Environment variable’s Effect on Go static compilation mechanism. In fact, there is a way to build projects that can be solved once and for all and ensure that offline compilation is consistent with online deployment environment, and that is the docker-based “cross-compilation solution”.

Docker is a very popular Linux container technology in recent years. Compared with traditional virtual machine technology, Docker occupies smaller system resources, has a small volume, and has a very fast startup speed. At the same time, Docker has been able to be quickly built on the mainstream operating systems Windows, macOS and Linux, which is very important for the cross-compilation in the next part of this article. Please refer to the Docker tutorial for more details about containers, and the installation method is very simple.

methods

Prepare a base image

In order to ensure the effect of one compilation and running everywhere (somewhat similar to JAVA virtual machine), it is necessary to use the same Docker base image for code compilation and deployment respectively. This article is based on the official release of DockerHub Golang: 1.14.3-Stretch customized image. The image is more convenient to compile and export the project code, and the image size is about 280MB, which is more acceptable. Here is the mirrored Dockerfile:

FROM golang: 1.14.3-Stretch MAINTAINER author <[email protected]> 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"]Copy the code

P.S. The Golang environment mirrored above has GOMODULE mode enabled by default, so the project needs to initialize go.mod for smooth compilation

How to use

With the Dockerfile above, we can then quickly build the image and instantiate the appropriate container to compile and deploy the project source code as follows:

1. Build an image
$docker build-t goBuilder :1.14.3-stretchCopy the code
2. Compile the go source for your project
# Assume your project directory gosrc contains the following files: /abspath/gosrc |---package | |---func1.go | |---func2.go |---go.mod |---config.yml |---main.go # Run the following container to compile your go project and export executable file to the current directory ~ $docker run - rm - it - v/abspath/gosrc / : / go/SRC/app gobuilderCopy the code
3. Run your GO project

There are two ways to run the GO project directly here: the first is to run your application by compiling and then executing the exported executable as described earlier. Gobuilder allows you to write specific dockerfiles for your main executable to build and instantiate your application image. For details, see the following construction methods:

    FROM gobuilder:1.14.3-stretch
    MAINTAINER author <[email protected]>
    WORKDIR /app
    COPY . .
    RUN chmod 777 main
    # master process
    ENTRYPOINT ["./main"]  
Copy the code

The second option is to run your Go file directly and start the application process. This is also based on the GoBuilder image. When starting, just mount the project and modify the ENTRYPOINT and CMD parameters.

If you need the container application to run in the background, Simply change - it to - d ~ $docker run - name YourAppName - it - v/abspath/gosrc / : / go/SRC/app - entrypoint go gobuilder run main. GoCopy the code

conclusion

This article mainly introduces a method to compile and run applications based on Docker, which can be consistent deployment on any machine (Linux, macOS and Windows) with Docker environment. It can achieve the effect of compiling once and running everywhere, which is very similar to JAVA virtual machine, has the same charm. By pulling the image and instantiating the container, you can also avoid the pain of setting up a runtime environment every time on a new machine. I am a small white, still in continuous learning, so if there are mistakes and omissions, but also hope to correct, thank you!