在生产环境的插件中安装 `eth` gem 时遇到困难

我不得不在一个插件中安装 eth gem,但遇到了很大的困难。它依赖于许多其他 gem,其中一些 gem 包含原生扩展。如果你想尝试一下,这是依赖列表。

gem 'pkg-config', '1.4.7', require: false
gem 'mkmfmf', '0.4', require: false
gem 'keccak', '1.3.0', require: false
gem 'zip', '2.0.2', require: false
gem 'mini_portile2', '2.7.0', require: false
gem 'rbsecp256k1', '5.1.0', require: false
gem 'konstructor', '1.0.2', require: false
gem 'ffi', '1.15.5', require: false
gem 'ffi-compiler', '1.0.1', require: false
gem 'scrypt', '3.0.7', require: false
gem 'eth', '0.5.1', require: false
gem 'siwe', '1.0.0', require: false

问题出在 rbsecp256k1。它试图要求 mini_portile2 来构建其原生扩展,但即使它已安装并被 require,也找不到它。我已经付出了巨大的努力,比如 fork 了 gem 并手动要求绝对路径,还尝试将 mini_portile2 字面克隆到 rbsecp256k1 中并从那里要求它,但到目前为止都没有成功。

任何帮助都将不胜感激。

2 个赞

我终于找到了一个变通方法。我稍后会分享。

3 个赞

我做了以下操作。我登录到服务器并进入了 docker 容器。

  • 创建一个名为 gems 的文件夹

  • 创建一个子目录 2.7.5tests-passed 上生产 discourse 使用的 ruby 版本)

  • cd 回到 gems 文件夹

  • 以这种方式运行命令

    RUBY_VERSION=2.7.5
    gem install pkg-config -v 1.4.7 -i $RUBY_VERSION --no-document --ignore-dependencies --no-user-install
    gem install mkmfmf -v 0.4 -i $RUBY_VERSION --no-document --ignore-dependencies --no-user-install
    ...
    

    注意:这些与 discourse 运行(尝试运行但失败)安装 gem 的命令完全相同。

  • 现在压缩这个文件夹。

  • 退出 docker 容器,并使用 docker cp 命令将 zip 文件复制到 docker 容器外部。

  • 通过 filezilla 或 vscode 连接到您的服务器并下载 zip 文件。

  • 将其解压到插件的根文件夹。这样您的插件文件夹现在将包含 gems 目录。

  • 现在将 gems 文件夹与插件一起推送到 github。

现在,当您在 discourse 上使用此插件重建时,discourse 将使用您提供的依赖项,而不会尝试安装它们。这是一个临时的解决方法,一旦 discourse 升级 ruby 版本,就需要重新执行。

但最大的问题是,为什么在 discourse 尝试运行时,与在终端运行时相同的命令会失败。这非常值得研究,我希望有一个简单的解决方法。

3 个赞

我最近在 DEV: Don't load bundler when installing plugin gem. (#16117) · discourse/discourse@6b8c622 · GitHub 中修复了这个问题。

3 个赞

太棒了,谢谢。 :clap:

您能否将此修复程序挑选到 stable 分支,@tgxworld

1 个赞

已在以下位置完成:

3 个赞