最佳实践:这才是构建 Go 语言 Docker 镜像该有的姿势

Go语言精选

共 2357字,需浏览 5分钟

 ·

2020-07-31 18:21

点击上方蓝色“Go语言中文网”关注我们,领全套Go资料,每天学习 Go 语言

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

Single build

下面是 Go 语言 Hello World 代码:

package main

import "fmt"

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

接着用 alpine[1] 的 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[2],将二进制文件直接扔进去即可,在编译可执行文件时需加入特定参数才可以:

$ 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[3] 镜像构建,并为所有标准证书颁发机构添加了根证书。

完整的 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。

本文作者:AppleBoy

原文链接:https://blog.wu-boy.com/2017/04/build-minimal-docker-container-using-multi-stage-for-go-app/

参考资料

[1]

alpine: https://hub.docker.com/_/alpine/

[2]

scratch: https://hub.docker.com/_/scratch/

[3]

scratch: https://registry.hub.docker.com/u/library/scratch/



推荐阅读


学习交流 Go 语言,扫码回复「进群」即可


站长 polarisxu

自己的原创文章

不限于 Go 技术

职场和创业经验


Go语言中文网

每天为你

分享 Go 知识

Go爱好者值得关注


浏览 35
点赞
评论
收藏
分享

手机扫一扫分享

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

手机扫一扫分享

分享
举报