无法在 M1 Mac 上的 docker 容器中加载 nokogiri
Unable to load nokogiri in docker container on M1 Mac
我正在 M1 mac 上构建 linux docker 图像(如果重要,来自 ruby:3.0.2-alpine3.12)。
当我尝试在我的容器中执行 bundle exec 时,ruby 抱怨它无法加载 nokogiri。如果我只是开始 ruby 并尝试要求 nokogiri,我会得到相同的结果:
bash-5.0# irb
irb(main):001:0> require 'nokogiri'
<internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require': cannot load such file -- nokogiri (LoadError)
from <internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from (irb):1:in `<main>'
from /usr/local/lib/ruby/gems/3.0.0/gems/irb-1.3.5/exe/irb:11:in `<top (required)>'
from /usr/local/bin/irb:23:in `load'
from /usr/local/bin/irb:23:in `<main>'
安装了gem
ls -la /app/vendor/bundle/ruby/3.0.0/gems/
<snip>
drwxr-xr-x 6 root root 4096 Feb 2 22:43 nokogiri-1.13.1-aarch64-linux
<snip
一件有点奇怪的事情是
bash-5.0# ruby --version
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [aarch64-linux-musl]
我不认为 musl 平台导致了不匹配。我们的生产 mac 内核是 amd64,那里有类似的 amd64/amd64-musl 不匹配,但它们 运行 容器是正确的。
有没有办法让它工作?
解决方法
我已经能够通过在捆绑时禁用预编译的 gems 来解决这个问题,但如果不必这样做就好了。 (我们有一个混合的M1/Intel开发组,外国架构的交叉编译似乎很长)。
我有一个 Rails 应用程序有类似的问题,它依赖于我的 Macbook M1 上基于 Alpine 的容器上的 Nokogiri 运行。这是我所做的:
看了Nokogiri documentation,发现其实支持aarch64-linux
(Docker容器内部使用的架构),但是需要glibc >= 2.29
.
我远不是专家,但据我所知,Alpine 发行版不包括 glibc
但 musl
。还好有are ways to run programs that need glibc
in Alpine.
我个人是按照第一种方式安装的gcompat
。我只需要将 gcompat
添加到要在我的 Dockerfile
.
中安装的软件包列表中
RUN apk add --no-cache ... gcompat
更改之后,一切顺利,Rails 应用程序启动没有问题。
同样,我不是专家,以上内容可能不准确,但它对我来说很神奇。希望对你也有帮助。
我正在 M1 mac 上构建 linux docker 图像(如果重要,来自 ruby:3.0.2-alpine3.12)。
当我尝试在我的容器中执行 bundle exec 时,ruby 抱怨它无法加载 nokogiri。如果我只是开始 ruby 并尝试要求 nokogiri,我会得到相同的结果:
bash-5.0# irb
irb(main):001:0> require 'nokogiri'
<internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require': cannot load such file -- nokogiri (LoadError)
from <internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from (irb):1:in `<main>'
from /usr/local/lib/ruby/gems/3.0.0/gems/irb-1.3.5/exe/irb:11:in `<top (required)>'
from /usr/local/bin/irb:23:in `load'
from /usr/local/bin/irb:23:in `<main>'
安装了gem
ls -la /app/vendor/bundle/ruby/3.0.0/gems/
<snip>
drwxr-xr-x 6 root root 4096 Feb 2 22:43 nokogiri-1.13.1-aarch64-linux
<snip
一件有点奇怪的事情是
bash-5.0# ruby --version
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [aarch64-linux-musl]
我不认为 musl 平台导致了不匹配。我们的生产 mac 内核是 amd64,那里有类似的 amd64/amd64-musl 不匹配,但它们 运行 容器是正确的。
有没有办法让它工作?
解决方法
我已经能够通过在捆绑时禁用预编译的 gems 来解决这个问题,但如果不必这样做就好了。 (我们有一个混合的M1/Intel开发组,外国架构的交叉编译似乎很长)。
我有一个 Rails 应用程序有类似的问题,它依赖于我的 Macbook M1 上基于 Alpine 的容器上的 Nokogiri 运行。这是我所做的:
看了Nokogiri documentation,发现其实支持
aarch64-linux
(Docker容器内部使用的架构),但是需要glibc >= 2.29
.我远不是专家,但据我所知,Alpine 发行版不包括
glibc
但musl
。还好有are ways to run programs that needglibc
in Alpine.我个人是按照第一种方式安装的
中安装的软件包列表中gcompat
。我只需要将gcompat
添加到要在我的Dockerfile
.RUN apk add --no-cache ... gcompat
更改之后,一切顺利,Rails 应用程序启动没有问题。
同样,我不是专家,以上内容可能不准确,但它对我来说很神奇。希望对你也有帮助。