开启交叉编译,需要设置GOOS和/或GOARCH。
例如,假设在64位的Mac上:
docker run -e GOOS=darwin -e GOARCH=amd64 -v /tmp/crosstest:/go/bin
golang go get github.com/golang/example/hello/…
交叉编译的输出不是直接在$GOPATH/bin,而是在$GOPATH/bin/$GOOS_$GOARCH.。换言之,想运行程序,得执行/tmp/crosstest/darwin_amd64/hello.。
直接安装到$PATH
如果在Linux上,甚至可以直接安装到系统bin目录:
docker run -v /usr/local/bin:/go/bin
golang get github.com/golang/example/hello/…
然而,在Mac上,尝试用/usr作为一个卷将不能挂载Mac的文件系统到容器。会挂载Moby VM(小Linux VM藏在工具栏Docker图标的后面)的/usr目录。(译注:目前Docker for Mac版本可以自定义设置挂载路径)
但可以使用/tmp或者在你的home目录下的什么其它目录,然后从这里复制。
创建依赖镜像
我们用这种技术产生的Go二进制文件是静态链接的。这意味着所有需要运行的代码包括所有依赖都被嵌入了。动态链接的程序与之相反,不包含一些基本的库(像“libc”)并且使用系统范围的复制,是在运行时确定的。
这意味着可以在容器里放弃Go编译好的程序,没有别的,并且它会运行。
我们试试!
scratch镜像
Docker生态系统有一个特殊的镜像:scratch.这是一个空镜像。它不需要被创建或者下载,因为定义的就是空的。
给新的Go依赖镜像创建一个新的空目录。
在这个新目录,创建下面的Dockerfile:
FROM scratch
COPY ./hello /hello
ENTRYPOINT [“/hello”]
这意味着:从scratch开始(一个空镜像),增加hello文件到镜像的根目录,*定义hello程序为启动这个容器后默认运行的程序。
然后,产生hello二进制文件如下:
docker run -v $(pwd):/go/bin –rm
golang go get github.com/golang/example/hello/…
注意:不需要设置GOOS和GOARCH,正因为,想要一个运行在Docker容器里的二进制文件,不是在主机上。所以不用设置这些变量!
然后,创建镜像:
docker build -t hello .
测试它:
docker run hello
(将显示“Hello, Go examples!”)
最后但不重要,检查镜像的大小:
docker images hello
如果一切做得正确,这个镜像大约2M。相当好!
构建东西而不推送到Github
当然,如果不得不推送到GitHub,每次编译都会浪费很多时间。
想在一个代码段上工作并在容器中创建它时,可以在golang容器里挂载一个本地目录到/go。所以$GOPATH是持久调用:docker run -v $HOME/go:/go golang ….
但也可以挂载本地目录到特定的路径上,来“重载”一些包(那些在本地编辑的)。这是一个完整的例子:










