分享
  1. 首页
  2. 文章

创建最小的golang容器镜像

openthings · · 2971 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Create the smallest and secured golang docker image based on scratch

When we are building a docker Image, the first idea is using the default official image.

FROM golang
FROM nginx
FROM openjdk

There is an official Docker image for Go.

$ docker image list
golang latest 1c1309ff8e0d 10 days ago 779MB

Ouch 779 MB just for an empty image ... this is crazy ????

There is lightweight Alpine Docker image for Go.

Check the Alpine linux page for more informations.

FROM golang:alpine

This is smaller but too large for a production image with nothing

$ docker image list
golang alpine bbab7aea1231 7 weeks ago 269MB

Use Multi-stage builds

Thanks to docker multi-stage builds, we can build our application in a docker alpine image an produce a small image with only a binary in a scratch image.

Use multi-stage builds
Multi-stage builds are a new feature requiring Docker 17.05 or higher on the daemon and client. Multistage builds are...docs.docker.com

OK, it’s time to build a smaller image with multi-stage build

Before that we gonna see docker scratch image, only 2MB image. Perfect for our go static binary.

# STEP 1 build executable binary
FROM golang:alpine as builder
COPY . $GOPATH/src/mypackage/myapp/
WORKDIR $GOPATH/src/mypackage/myapp/
#get dependancies
RUN go get -d -v
#build the binary
RUN go build -o /go/bin/hello
# STEP 2 build a small image
# start from scratch
FROM scratch
# Copy our static executable
COPY --from=builder /go/bin/hello /go/bin/hello
ENTRYPOINT ["/go/bin/hello"]

Oh cool only 21.2MB with everything i need for my go app.

$ docker image list
hello latest bbab7aea1234 3 hours ago 21.2MB

But we can optimize it, by removing debug informations and compile only for linux target and disabling cross compilation.

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags="-w -s" -o /go/bin/backoffice

Now we have a small image only 13.6MB, almost ready for production

$ docker image list
hello latest bbab7aea1234 2hours ago 13.6MB

Let’s build a more secure docker image

Just some reminders :

  • Run only one process in a container.
  • Never run a process as root in a container.
  • Never store data in a container, do it in a volume
  • Never store credentials in a container, do it in a volume
  • Keep your image up to date
  • Verify third-party container repositories
  • Use tool like docker-security-scanning
  • May the force be with you ????

OK, let’s do that with scratch image.

We have to create a new user on the builder image and copy the /etc/passwd file from the builder to te scratch image. Finally we can use appuser to launch the binary.

# STEP 1 build executable binary
FROM golang:alpine as builder
# Create appuser
RUN adduser -D -g '' appuser
COPY . $GOPATH/src/mypackage/myapp/
WORKDIR $GOPATH/src/mypackage/myapp/
#get dependancies
RUN go get -d -v
#build the binary
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags="-w -s" -o /go/bin/backoffice
# STEP 2 build a small image
# start from scratch
FROM scratch
COPY --from=builder /etc/passwd /etc/passwd
# Copy our static executable
COPY --from=builder /go/bin/hello /go/bin/hello
USER appuser
ENTRYPOINT ["/go/bin/hello"]

Always export with port > 1024 as possible

OK, now we have a more secure image. But if we expose our docker with a port < 1024, we need some privileges for that.

OK so let’s expose always our binary with a port > 1024

COPY --from=builder /etc/passwd /etc/passwd
# Copy our static executable
COPY --from=builder /go/bin/hello /go/bin/hello
USER appuser
EXPOSE 9292
ENTRYPOINT ["/go/bin/hello"]

Add SSL ca certificates

Perfect, but to be secure we need to expose our services with SSL isn’t it ?

By default scratch image is not provided with SSL CA certificates. But with multi-step we can provide it.

# STEP 1 build executable binary
FROM golang:alpine as builder
# Install SSL ca certificates
RUN apk update && apk add git && apk add ca-certificates
# Create appuser
RUN adduser -D -g '' appuser
COPY . $GOPATH/src/mypackage/myapp/
WORKDIR $GOPATH/src/mypackage/myapp/
#get dependancies
RUN go get -d -v
#build the binary
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags="-w -s" -o /go/bin/backoffice
# STEP 2 build a small image
# start from scratch
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /etc/passwd /etc/passwd
# Copy our static executable
COPY --from=builder /go/bin/hello /go/bin/hello
USER appuser
ENTRYPOINT ["/go/bin/hello"]
If you have any advice about security, please let me know :)

有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:openthings

查看原文:创建最小的golang容器镜像

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2971 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏