TLDR;将postgresql-dev 替换为'postgresql-dev<12.2-r0'
如:
RUN apk add --update --no-cache \
...\
'postgresql-dev<12.2-r0'\
...
您将获得(以ruby:2.6.6-alpine 作为基础图像)305Mo 图像大小,与基础图像为ruby:2.6.5-alpine 时的 265Mo 足够接近。
详情:
我似乎无法让imagelayers.io 正常工作,所以我转而使用wagoodman/dive 来检查这两个图像的层。
在这两种情况下,我都得到了 50Mo 的图像(2.6.5-alpine 为 49.5)
所以基础镜像在这里不是问题。
区别在于:
从 2.6.6 完成后,您的依赖项列表将安装以下 附加 包:
{+Installing xz-libs (5.2.5-r0)+}
{+Installing libxml2 (2.9.10-r4)+}
{+Installing llvm10-libs (10.0.0-r2)+}
{+Installing clang-libs (10.0.0-r2)+}
{+Installing clang (10.0.0-r2)+}
{+Installing llvm10 (10.0.0-r2)+}
{+Installing icu-libs (67.1-r0)+}
{+Installing icu (67.1-r0)+}
{+Installing icu-dev (67.1-r0)+}
这是由于:
我已将this gist 添加到您的 Dockerfile 中
RUN apk info | xargs -n1 -I{} apk info -s {} | xargs -n4 | awk '{print $4,$1}' | sort -rn
我明白了
85360640 gcc-9.2.0-r4
对比
109056000 gcc-9.3.0-r2
63430656 llvm10-libs-10.0.0-r2
62976000 clang-libs-10.0.0-r2
-
gcc 更大(从 85Mo 到 109)
-
llvm10-libs 和 clang-libs 添加 125Mo
如 Jérôme Petazzoni 中的“The Quest for Minimal Docker Images, part 2”所示,最好使用 multi-stage build,例如:
FROM alpine
RUN apk add build-base
COPY hello.c .
RUN gcc -o hello hello.c
FROM alpine
COPY --from=0 hello .
CMD ["./hello"]
注意,寻找大小增加的根本原因:
额外的依赖是patch,它本身依赖musl:非常小。
大小问题与build-base无关
让我们将您的Dockerfile 更改为:
RUN apk add --update
RUN apk info build-base
RUN apk add --update --no-cache build-base
RUN apk add --update --no-cache postgresql-dev
RUN apk add --update --no-cache vim
RUN apk add --update --no-cache tzdata
RUN apk add --update --no-cache bash
RUN apk add --update --no-cache less
实用程序dive 将显示postgresql-dev 是Alpine 3.12 需要clang 的那个。
这三个附加依赖项是:
从Alpine 3.10+ to 3.12 开始,安装postgresql 意味着启动clang,但postgresql-dev 的大小差异在两者之间巨大。
- Alpine 3.11 或更低版本:
postgresql-dev 为 15Mo
- Alpine 3.12:215Mo for
postgresql-dev
这是因为 Alpine postgresql APKBUILD 的依赖关系最近发生了变化。
见:
第一次提交的评论提到:
由于我们在构建 PostgreSQL 时启用了 JIT 支持,因此使用 PGXS 构建扩展需要 clang 和 llvm-lto。
可能是因为docker-library/postgres issue 475: "JIT --with-llvm"
... 这导致 docker-library/postgres issue 651: "postgres:12.0-alpine upgrade to postgres:12.1-alpine double size"。
见“Postgresql 12: What Is JIT compilation?”
即时 (JIT) 编译是将某种形式的解释程序评估转换为本机程序并在运行时执行此操作的过程。
例如,可以生成一个特定于该表达式的函数,并且可以由CPU,产生加速。
当 PostgreSQL 使用 --with-llvm 构建时,PostgreSQL 已内置支持使用 LLVM 执行 JIT 编译。
because now:
对于支持LLVM 的 PostgreSQL 12 系统,默认启用即时编译,即“JIT”。
这反映在how postgresql is built for Docker:从issue 643 看到commit c8bf23b,并在docker-library/official-images PR 7042 中合并。
所以...可能的解决方法:限制postgresql-dev 的版本,如“How to install a specific package version in Alpine?”中所述:
RUN apk add --update --no-cache 'postgresql-dev<12.2-r0'
这将确保使用 15Mo postgresql 而不是 215Mo。