Blog
Blog copied to clipboard
Go交叉编译
Go交叉编译
标签(空格分隔): Go
更新了一版Frp,因为升级不兼容旧版本的缘故,对之前的Frps的Dockerfile进行了升级。主要变动是把之前Bundle的Frps修改为Build时编译。
因为Frp是用Go写的,顺便了解了一下Go的包管理。去中心化很有意思。
作者提供了Dockerfile,改起来很快。
因为原版的Dockerfile直接使用Golang镜像作为Base,最终生成的镜像比较大。Go的跨平台做的很方便,按照之前Frps的用法,只需要下载好对应平台的可执行文件就好了,不像Java还要要求JRE。那么使用Golang镜像作为Base,提供的Go编译环境实际上已经没有用了。
之前看到过分阶段构建的概念,发现Docker也实现了。就用分阶段构建的方式修改了一下Dockerfile。
坑在Alpine默认没有带make
和bash
。又想偷懒,直接用golang:1.10
作为base编译了,然后发现在Alpine作为Base的Production镜像上无法启动。
原因是
采用了不同libc实现的debian系和alpine系存在不兼容的情况(golang:1.10基于debian)
解决方案有两种
- 使用Alpine编译,在编译前先
apk --add make bash
,由于是分阶段构建,这部份的Clean操作就忽略掉了先。 - 还是使用golang:1.10编译,需要使用静态构建。就是把之前用到动态链接库的地方直接静态编译进可执行文件中去。
CGO_ENABLED=0
标志使用静态构建。
方法2的优点是可以使用更新的Base镜像,比如scratch。
中途还补充了一下Dockerfile: ENTRYPOINT和CMD的区别的概念。
Href
- multi-stage-image-build-in-docker https://tonybai.com/2017/11/11/multi-stage-image-build-in-docker/
- Dockerfile: ENTRYPOINT和CMD的区别 https://zhuanlan.zhihu.com/p/30555962