Docker Ruby 2.6.6-alpine 是 Ruby-2.6.5-alpine 的两倍

Docker Ruby 2.6.6-alpine is twice as big as Ruby-2.6.5-alpine

Docker 图像使用 ruby-2.6.6-alpine 创建一个 498mb 图像大小。但是,当我降级到 ruby-2.6.5-alpine 时,它​​又回到了 266mb。 2.6.6 版本几乎是两倍大。为什么会这样?

# RESULTS IN 266MB
FROM ruby:2.6.5-alpine
RUN apk add --update --no-cache \
        build-base \
        postgresql-dev \
        vim \
        tzdata \
        bash \
        less

# RESULTS IN 498MB
FROM ruby:2.6.6-alpine
RUN apk add --update --no-cache \
        build-base \
        postgresql-dev \
        vim \
        tzdata \
        bash \
        less

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 work properly, so I fall back to 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 ,}' | 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-libsclang-libs 添加 125Mo

如图“The Quest for Minimal Docker Images, part 2" from Jérôme Petazzoni, it is best to use a 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, which itself depends on 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 是需要 clang 的 Alpine 3.12。

这三个附加依赖项是:

Alpine 3.10+ to 3.12 开始,安装 postgresql 意味着开始 clang,但 postgresql-dev 的尺寸差异 巨大 两人

  • Alpine 3.11 或更低版本:postgresql-dev
  • 为 15Mo

  • Alpine 3.12:215Mo postgresql-dev

这是因为 Alpine postgresql APKBUILD.
的依赖关系最近发生了变化 参见:

第一次提交的评论提到:

Since we build PostgreSQL with JIT support enabled, clang and llvm-lto are required for building extensions with PGXS.

可能是因为 docker-library/postgres issue 475:“JIT --with-llvm

... 导致 docker-library/postgres issue 651: "postgres:12.0-alpine 升级到 postgres:12.1-alpine 双尺寸 ".

参见“Postgresql 12: What Is JIT compilation?

Just-in-Time (JIT) compilation is the process of turning some form of interpreted program evaluation into a native program, and doing so at run time.

For example, instead of using general-purpose code that can evaluate arbitrary SQL expressions to evaluate a particular SQL predicate like WHERE a.col = 3, it is possible to generate a function that is specific to that expression and can be natively executed by the CPU, yielding a speedup.

PostgreSQL has builtin support to perform JIT compilation using LLVM when PostgreSQL is built with --with-llvm.

全部 because now:

For PostgreSQL 12 systems that support LLVM, just-in-time compilation, aka "JIT," is enabled by default.

这反映在how postgresql is built for Docker: see commit c8bf23b from issue 643, and merged in 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。