# Adapt the two following environment variables if you are not running on a Mac
export GOOS=darwin GOARCH=amd64
mkdir go-and-docker-is-love
cd go-and-docker-is-love
git clone git://github.com/golang/example
cat example/hello/hello.go
sed -i .bak s/olleH/eyB/ example/hello/hello.go
docker run --rm
-v $(pwd)/example:/go/src/github.com/golang/example
-v $(pwd):/go/bin/${GOOS}_${GOARCH}
-e GOOS -e GOARCH
golang go get github.com/golang/example/hello/...
./hello
# Should display "Bye, Go examples!"
网络包和CGo的特殊情况
进入真实的Go代码世界前,必须承认的是:在二进制文件上有一点点偏差。如果在使用CGo,或如果在使用net包,Go链接器将生成一个动态库。这种情况下,net包(里面确实有许多有用的Go程序!),罪魁祸首是DNS解析。大多数系统都有一个花哨的,模块化的名称解析系统(像名称服务切换),它依赖于插件,技术上,是动态库。默认地,Go将尝试使用它;这样,它将产生动态库。
我们怎么解决?
重用另一个版本的libc
一个解决方法是用一个基础镜像,有那些程序功能所必需的库。几乎任何“正规”基于GNU libc的Linux发行版都能做到。所以,例如,使用FROM debian或FROM fedora,替代FROM scratch。现在结果镜像会比原来大一些;但至少,大出来的这一点将和系统里其它镜像共享。
注意:这种情况不能使用Alpine,因为Alpine是使用musl库而不是GNU libc。
使用自己的libc
另一个解决方案是像做手术般地提取需要的文件,用COPY替换容器里的。结果容器会小。然而,这个提取过程困难又繁琐,太多更深的细节要处理。
如果想自己看,看看前面提到的ldd和名称服务切换插件。
用netgo生成静态二进制文件
我们也可以指示Go不用系统的libc,用本地DNS解析代替Go的netgo。
要使用它,只需在go get选项加入-tags netgo -installsuffix netgo。
-tags netgo指示工具链使用netgo。
-installsuffix netgo确保结果库(任何)被一个不同的,非默认的目录所替代。如果做多重go get(或go build)调用,这将避免
代码创建和用不用netgo之间的冲突。如果像目前我们讲到的这样,在容器里创建,是完全没有必要的。因为这个容器里面永远没有其他Go代码要编译。但它是个好主意,习惯它,或至少知道这个标识存在。
SSL证书的特殊情况
还有一件事,你会担心,你的代码必须验证SSL证书;例如,通过HTTPS联接外部API。这种情况,需要将根证书也放入容器里,因为Go不会捆绑它们到二进制文件里。
安装SSL证书
再次,有很多可用的选择,但最简单的是使用一个已经存在的发布里面的包。










