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

Xtr*_*fox 7 ruby docker alpine-linux

使用 ruby​​-2.6.6-alpine 的 Docker 镜像创建了一个 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
Run Code Online (Sandbox Code Playgroud)

Von*_*onC 11

TLDR;替换postgresql-dev'postgresql-dev<12.2-r0'

如:

RUN apk add --update --no-cache \
...\
'postgresql-dev<12.2-r0'\
...
Run Code Online (Sandbox Code Playgroud)

您将获得(ruby:2.6.6-alpine作为基本图像)一个 305Mo 的图像大小,当基本图像为ruby:2.6.5-alpine.


细节:

我似乎无法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)+}
Run Code Online (Sandbox Code Playgroud)

这是由于以下之间的差异:

将此要点添加到您的 Dockerfile

RUN apk info | xargs -n1 -I{} apk info -s {} | xargs -n4 | awk '{print $4,$1}' | sort -rn
Run Code Online (Sandbox Code Playgroud)

我懂了

85360640 gcc-9.2.0-r4
Run Code Online (Sandbox Code Playgroud)

对比

109056000 gcc-9.3.0-r2
63430656 llvm10-libs-10.0.0-r2
62976000 clang-libs-10.0.0-r2
Run Code Online (Sandbox Code Playgroud)
  • gcc 更大(从 85Mo 到 109)
  • llvm10-libsclang-libs添加 125Mo

Jérôme Petazzoni 的The Quest for Minimal Docker Images, part 2 ”中所示,最好使用多阶段构建,例如:

FROM alpine
RUN apk add build-base
COPY hello.c .
RUN gcc -o hello hello.c

FROM alpine
COPY --from=0 hello .
CMD ["./hello"]
Run Code Online (Sandbox Code Playgroud)

注意,寻找尺寸增加的根本原因:

额外的依赖是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
Run Code Online (Sandbox Code Playgroud)

该实用程序dive将显示postgresql-devclangAlpine 3.12 所需要的。

这三个额外的依赖是:

高山3.10+ 3.12,安装postgresql方式着手clang,但在大小的差异postgresql-dev巨大的两者之间。

  • Alpine 3.11 或更低:15Mo for postgresql-dev

高山 3.11 postgresq-dev

  • 阿尔卑斯3.12:215Mopostgresql-dev

高山 3.12 postgresql-dev

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

第一次提交的评论提到:

由于我们在启用 JIT 支持的情况下构建 PostgreSQL,clang并且llvm-lto需要使用 PGXS 构建扩展。

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

...导致docker-library/postgres问题 651:“ postgres:12.0-alpine 升级到 postgres:12.1-alpine 双倍大小”。

请参阅“ Postgresql 12:什么是 JIT 编译?

即时 (JIT) 编译是将某种形式的解释程序评估转换为本地程序并在运行时执行此操作的过程。

例如,代替使用可以评估任意 SQL 表达式的通用代码来评估特定的 SQL 谓词,例如WHERE a.col = 3,可以生成特定于该表达式的函数,并且可以由 CPU 本地执行,从而产生加速。

PostgreSQL 内置支持使用 LLVM 执行 JIT 编译--with-llvm

这一切都是因为现在

对于支持LLVM 的PostgreSQL 12 系统,即时编译,即“JIT”,默认处于启用状态。

这反映在PostgreSQL是如何为码头工人建:看到提交c8bf23b问题643,并在合并docker-library/official-imagesPR 7042

所以...可能的解决方法:限制 的版本postgresql-dev,如“如何在 Alpine 中安装特定软件包版本? ”中所述:

RUN apk add --update --no-cache 'postgresql-dev<12.2-r0'
Run Code Online (Sandbox Code Playgroud)

这将确保使用 15Mopostgresql而不是 215Mo。