无法在 M1 Mac 上的 docker 容器中加载 nokogiri

And*_*vis 11 rubygems nokogiri apple-m1

我正在 M1 mac 上构建一个 Linux docker 镜像(如果有的话,可以从 ruby​​:3.0.2-alpine3.12 开始)。

当我尝试在容器中执行捆绑执行时,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>'
Run Code Online (Sandbox Code Playgroud)

宝石已安装

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
Run Code Online (Sandbox Code Playgroud)

一件有点奇怪的事情是

bash-5.0# ruby --version
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [aarch64-linux-musl]
Run Code Online (Sandbox Code Playgroud)

我不认为 musl 平台导致了不匹配。我们的生产机器是 amd64,并且存在类似的 amd64/amd64-musl 不匹配问题,但它们可以正确运行容器。

有办法让它发挥作用吗?

解决方法

我已经能够通过在捆绑时禁用预编译 gem 来解决这个问题,但最好不必这样做。(我们有一个混合的 M1/Intel 开发组,外国架构的交叉编译似乎相当漫长)。

Ped*_*lan 45

我的 Rails 应用程序也遇到了类似的问题,该应用程序依赖于在我的 Macbook M1 上基于 Alpine 的容器上运行的 Nokogiri。这是我所做的:

  1. 阅读Nokogiri文档,我发现aarch64-linux(Docker容器内部使用的架构)实际上是支持的,但它需要glibc >= 2.29.

  2. 我远不是专家,但据我所知,Alpine 发行版不包括glibcbut musl。幸运的是,有一些方法可以在 Alpine 中运行需要的程序glibc

  3. 我个人采用的是第一个选项,即我安装了gcompat. 我只需要添加到gcompat要安装在我的Dockerfile.

    RUN apk add --no-cache ... gcompat

  4. 更改之后,一切进展顺利,Rails 应用程序启动时没有出现任何问题。

再说一次,我不是专家,上面的内容可能不准确,但它对我来说有魔力。我希望它也能帮助你。

  • 像冠军一样工作,谢谢! (4认同)
  • 你救了我的命。谢谢! (4认同)