本文展示如何将Node.js的Image大小从最初的943MB缩小到6.34kB Assembly Image的过程,并了解了一些可用于将来缩小容器镜像的技术。 Docker具有称为多阶段构建的功能,可轻松在具有所有必要依赖项的环境中构建代码,然后将生成的可执行文件复制到其他Image中。出于多种原因,这很有用,但是最明显的原因之一是Image大小!通过如下方式重构dockerfile:
### build stage ### FROM golang:1.14-alpine AS builder COPY . . RUN go build -o server . ### run stage ### FROM alpine:3.12 COPY --from=builder /go/server ./server COPY index.html index.html CMD ["./server"] |
Image结果就是13.2MB! 静态编译+Scratch image 13 MB还算不错,但是我们仍然可以使用一些技巧来使它变得更小。 有一个称为scratch的基本Image,其内容为空且大小为零。因为scratch里面没有任何内容,所以使用它构建的任何Image都必须带有所有必需的依赖项。 为了使基于go的服务器能够做到这一点,我们需要在编译步骤中添加一些标志,以确保将必要的库静态链接到可执行文件中:
### build stage ### FROM golang:1.14 as builder COPY . . RUN go build \ -ldflags "-linkmode external -extldflags -static" \ -a server.go ### run stage ### FROM scratch COPY --from=builder /go/server ./server COPY index.html index.html CMD ["./server"] |
具体来说,我们将链接模式设置为external,并将-static标志传递给外部链接器。 这两个更改使Image大小达到8.65MB ASM赢! 用Go之类的语言编写的小于10MB的图像几乎在任何情况下都足够小...但是我们可以缩小尺寸!Github用户nemasu在github上以汇编形式编写的全功能http服务器,名为assmttpd。 对其进行容器化所需要做的就是在运行提供的make release配方之前将一些构建依赖项安装到ubuntu基础Image中:
### build stage ### FROM ubuntu:18.04 as builder RUN apt update RUN apt install -y make yasm as31 nasm binutils COPY . . RUN make release ### run stage ### FROM scratch COPY --from=builder /asmttpd /asmttpd COPY /web_root/index.html /web_root/index.html CMD ["/asmttpd", "/web_root", "8080"] |
asmttpd然后将生成的可执行文件复制到 scratch image中,并使用调用CMD。这样产生的图像大小仅为6.34kB! 点击标题