Heroku 部署无法加载自定义 .bundle 文件



我在谷歌上搜索这个问题时遇到了很多麻烦,因为bundler不断出现。但是,我的问题在于我使用mkmf和 ruby c API 捆绑的 c 库。我已经将我的 c 代码编译成一个文件(例如my_library.bundle(,我已经在助手中需要它,require_relative "my_library"没有问题。

当我部署到 heroku 并收到错误时出现问题:

2019-08-14T19:09:15.452530+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require': cannot load such file -- /app/app/helpers/my_library (LoadError)

我可以在我的 heroku 应用程序上运行lscat,以验证文件是否存在以及内容是否匹配。当我使用RAILS_ENV=production在本地运行应用程序时,我也没有遇到任何问题。此外,运行heroku local web在我的机器上运行良好。

这与我的配置有关吗autoload_paths?我的主要问题是我似乎无法在本地调试它。

编辑:我注意到这个问题也出现在码头工人化的实例中。似乎容器化的某些东西似乎是问题所在。我什至尝试按照本指南创建一个 gem 来包含捆绑包,该指南在本地工作,但再次遇到查找文件时遇到的相同问题,但这次路径是相对于 gem,而不是我的项目。我仍然对导致此问题的原因感到困惑。

根据您发布的错误,Docker似乎没有指向正确的路径cannot load such file -- /app/app/helpers/my_library。如果正确,则应在 Dockerfile 中显式指定工作目录。

WORKDIR /path/to/project

之后,只需重建映像即可。

现在,如果这不起作用,您可以在项目中检查autoload_paths或自定义引导快照以避免自动加载路径出错。

您可以做的是将整个my_library作为本地 gem并将您的 Gemfile 指向它。 大致上,大纲如下:

  1. my_library的整个代码放在应用中的目录中,例如fixtures(与 Gemfile 处于同一级别(。
    app/
    ...
    fixtures/
    my_library/
    ext/
    ...
    lib/
    ...
    my_library.gemspec
    Rakefile
    Gemfile
    
  2. 将您的宝石文件指向my_library宝石:
    gem 'my_library', path: 'fixtures/my_library'
    
  3. 然后只需通过运行来更新您的Gemfile.lock
    bundle update
    

正如@jay-dorsey所提到的,该捆绑包确实需要在部署应用程序的服务器上编译才能使用。我遵循的创建宝石的两个指南都有一些错误信息。

  1. gem 应仅包含源文件,不包含已编译的源文件
  2. rakefile 应该引用ext.lib_dir = "lib/my_library"而不是ext目录
  3. gemspec 应该在其他依赖项之前添加rake-compiler开发依赖项
  4. 版本文件不应尝试加载扩展,因为它在 gemspec 中使用,这是在 gem 有机会被 rake/bundler 编译之前调用
  5. 无法在 Linux 计算机上读取.bundle文件

最新更新