Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

Gray-Ice

个人博客兼个人网站

本篇博文用于记录博主打包Go语言编写出的程序至镜像的经历。最终打包出了82MB的镜像。该镜像功能简单,仅为Gin的示例代码。

踩坑进行时

该标题下的内容只是详细记录一下博主的经历,想直接看最终做法的请直接翻到下一个标题。

我从Gin的README之中拷贝了示例代码,确认了它在本机可以运行,于是我就直接build了项目,之后将go build生成的二进制文件一同打包至镜像内,然后运行的时候提示我缺库。我试了各种编译参数,始终无法做出不依赖动态链接库的二进制文件。我感觉直接从我的机器上把库拷贝到镜像里有点蠢,于是就将GO环境(直接从官网下载的tar.gz包),项目所需的模块(GOPATH/pkg)和项目本身拷贝进golang镜像,然后编译,之后我收获了1.25GB的镜像.. lol

然后我在编译后将环境删掉,将镜像缩减到了900多MB,仍然太大了,于是我换用ubuntu镜像,往里放GO SDK,依赖和代码,编译完后删掉环境,做出了250多MB的镜像。但我心里还是觉得膈应,于是选择了另一种方法(见下一个标题内容)。

最终做法

新建一个容器,该容器基于一个基础的系统镜像,然后在构建的时候将go的环境和代码拷贝到镜像中,之后在镜像中编译程序,最后再将编译好的程序拷贝出来,再把这个编译好的程序打包进一个空系统(该系统需要与之前编译时用的系统相同),然后用这个空系统运行编译好的程序。

编译环境Dockerfile如下(最后一步rm其实没必要):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM ubuntu
ENV GOPATH /go/go
ENV GO111MODULE on
COPY ./pkg /go/pkg
COPY ./website /website
COPY ./go1.18.1.linux-amd64.tar.gz /go/go.tar.gz
RUN cd /go \
&& tar -xzvf ./go.tar.gz \
&& cp -r ./pkg/* /go/go/pkg \
&& export PATH=$PATH:$GOPATH/bin \
&& cd /website \
&& go build \
&& rm -rf /go
CMD bash

构建完成之后运行该镜像,将里面编译好的二进制文件拷贝出来:

1
docker cp bd8a52a3c05b:/website/server ./

之后将该二进制文件放进空系统,Dockerfile如下:

1
2
3
FROM  ubuntu
COPY ./server /server
CMD ["/server"]

然后就大功告成辣,这个镜像除了基础文件外就只剩这个二进制文件了,几乎做到了最小(有老哥做出了不依赖任何库的文件,放在alpine上,大小只有9M!!!但是我做不到 —— 或者说 我懒得做 ——我只要在alpine下搭一个编译环境就好了,但是太折腾了)。

评论



愿火焰指引你