Blog icon indicating copy to clipboard operation
Blog copied to clipboard

Go交叉编译

Open alwaystest opened this issue 6 years ago • 0 comments

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默认没有带makebash。又想偷懒,直接用golang:1.10作为base编译了,然后发现在Alpine作为Base的Production镜像上无法启动。

原因是

采用了不同libc实现的debian系和alpine系存在不兼容的情况(golang:1.10基于debian)

解决方案有两种

  1. 使用Alpine编译,在编译前先apk --add make bash,由于是分阶段构建,这部份的Clean操作就忽略掉了先。
  2. 还是使用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

alwaystest avatar Jun 02 '18 19:06 alwaystest