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)+}
这是由于两者的区别:
- docker ruby 2.6.6 alpine 基于
alpine:3.12
- docker ruby 2.6.5 alpine 基于 alpine 3.11(或 3.9)
我添加了 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-libs
和 clang-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"]
注释,寻找大小增加的根本原因:
build_base
for Alpine 3.9 有 7 个依赖项
build_base
for Alpine 3.11 有 7 个依赖项
- build_base for Alpine 3.12 有 8 个。
额外的依赖是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。
这三个附加依赖项是:
clang
(25Mo)
icu-dev
llvm10
(which itself depends on llvm10-libs
, 60Mo)
从 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
.
的依赖关系最近发生了变化
参见:
- commit f040d3a from Jakub Jirutka 添加
clang
和 llvm
.
- commit 2bf48a5 from Ariadne Conill 添加
icu-dev
.
第一次提交的评论提到:
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。
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)+}
这是由于两者的区别:
- docker ruby 2.6.6 alpine 基于
alpine:3.12
- docker ruby 2.6.5 alpine 基于 alpine 3.11(或 3.9)
我添加了 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-libs
和clang-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"]
注释,寻找大小增加的根本原因:
build_base
for Alpine 3.9 有 7 个依赖项build_base
for Alpine 3.11 有 7 个依赖项- build_base for Alpine 3.12 有 8 个。
额外的依赖是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。
这三个附加依赖项是:
clang
(25Mo)icu-dev
llvm10
(which itself depends onllvm10-libs
, 60Mo)
从 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
.
的依赖关系最近发生了变化
参见:
- commit f040d3a from Jakub Jirutka 添加
clang
和llvm
. - commit 2bf48a5 from Ariadne Conill 添加
icu-dev
.
第一次提交的评论提到:
Since we build PostgreSQL with JIT support enabled,
clang
andllvm-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。