使用 Docker Multi-Stage 编译 Go 程序最佳姿势

DevOps技术栈

共 2178字,需浏览 5分钟

 ·

2020-08-10 17:49

作者:AppleBoy

链接:http://suo.im/5KL8v2

本文通过 Go 语言的 Hello World 來介绍基于 Docker 的 Single build 及 Multiple build。

Single build

下面是 Go 语言 Hello World 代码:

package main

import "fmt"

func main() {
    fmt.Println("Hello World!")
}

接着用 alpine 的 Go 语言 Image 来编译出可执行文件。

FROM golang:alpine
WORKDIR /app
ADD . /app
RUN cd /app && go build -o app
ENTRYPOINT ./app

接着执行如下编译指令:

$ docker build -t appleboy/go-app .
$ docker run --rm appleboy/go-app

最后检查看看编译出来的 Image 大小,使用docker images | grep go-app,会发现大小为 258 MB

Multiple build

Multiple build 则是可以在Dockerfile使用多个不同的 Image 来源,请看看底下例子:

# build stage
FROM golang:alpine AS build-env
ADD . /src
RUN cd /src && go build -o app

# final stage
FROM alpine
WORKDIR /app
COPY --from=build-env /src/app /app/
ENTRYPOINT ./app

从上面可以看到透过AS--from互相沟通,以前需要写两个 Dockerfile,现在只要一个就可以搞定。

$ docker build -t appleboy/go-app .
$ docker run --rm appleboy/go-app

会发现最后大小为 6.35 MB,比上面是不是小了很多。

最小 Image

6.35 MB 是最小的 Image 了吗?一个简单的 Hello World 可执行文件,用 Docker 包起来竟然要 6.35,其实不用这么大,我们可以透过 Dokcer 所提供的最小 Image:scratch,将二进制文件直接扔进去即可,在编译可执行文件时需加入特定参数才可以:

$ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app

在通过 Docker 包起来:

FROM centurylink/ca-certs

ADD app /

ENTRYPOINT ["/app"]

编译出来大小为:1.81MB,相信这是最小的 Image 了。

注:centurylink/ca-certs 是一个基于 Docker 的基础镜像,它基于 scratch 镜像构建,并为所有标准证书颁发机构添加了根证书。

完整的 Dockerfile:

# build stage
FROM golang:alpine AS build-env
ADD . /src
RUN cd /src && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app

# final stage
FROM centurylink/ca-certs
COPY --from=build-env /src/app /
ENTRYPOINT ["/app"]

总结

Multiple build 非常方便,这样就可以将多个步骤全部合并在一个 Dockerfile 处理掉,像是底下例子:

from debian as build-essential
arg APT_MIRROR
run apt-get update
run apt-get install -y make gcc
workdir /src

from build-essential as foo
copy src1 .
run make

from build-essential as bar
copy src2 .
run make

from alpine
copy --from=foo bin1 .
copy --from=bar bin2 .
cmd ...

用一个 Dockerfile 产生多个可执行文件,最后再用 alpine 打包成 Image。

- END -

精彩文章推荐:

从网管到架构师再到微创业,我这9年的成长感悟

12年老司机总结的 5 条面试忠告,终身受用

一篇漫画带你了解 Linux 内核长啥样!

SSH只能用于远程Linux主机?那说明你见识太小了!

10 个Linux Awk文本处理经典案例

Linux 系统故障排查,看这一篇就够了

10 分钟部署一个 Kubernetes 集群

部署一套完整的Kubernetes高可用集群(二进制)




点亮,服务器三年不宕机

浏览 15
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报