首页 > 解决方案 > 带有 Rails 的 Google App Engine Ruby 标准环境的正确 Ruby 版本

问题描述

使用Google为Google App Engine Ruby 2.5标准环境提供的默认app.yaml配置,使用Rails时无法成功部署。如果我在本地使用 Ruby 2.5.5,并且在我的.ruby-versionandGemfile中,部署失败并显示:

Your Ruby version is 2.5.7, but your Gemfile specified 2.5.5.

如果我在本地和我的文件中使用 Ruby 2.5.7 Gemfile.ruby-version则部署成功,但访问该应用程序会导致日志中出现以下错误:

bundler: failed to load command: rails (/srv/vendor/bundle/ruby/2.5.0/bin/rails)
Bundler::RubyVersionMismatch: Your Ruby version is 2.5.5, but your Gemfile specified 2.5.7

请注意,我已正确设置.gcloudignore包含.ruby-version和其他重要的点文件,这些点文件默认被应用引擎忽略。

相当的困境!

您可以使用此 repo 重现我的构建:https ://github.com/sam0x17/ruby_standard_environment_version_issue

标签: ruby-on-railsrubygoogle-app-enginegoogle-cloud-platformruby-2.5

解决方案


这是 Ruby App Engine 运行时团队的官方说法。

如果您的 Gemfile 中有 Ruby 版本约束,请始终使用悲观的版本约束(或其他允许更新补丁级别的机制),而不是锁定到特定的补丁级别。例如,使用类似的东西ruby "~> 2.5.5"来表示 2.5.5 或任何更新的补丁级别,而不是ruby "2.5.5"ruby "2.5.7"。这不是临时解决方法,而是 App Engine 标准的实际要求和最佳做法。

原因是双重的。在推出新的 Ruby 版本期间,可能会在短时间内在bundle install与应用程序本身不同的 Ruby 补丁级别上运行。这就是您遇到的情况,这显然是预期的行为,因为“捆绑构建器”组件是独立于运行时映像推出的。

但更重要的是,App Engine 标准可能会随时升级您的 Ruby 补丁级别。您的应用程序今天可能在 Ruby 2.5.6 上运行,但明天您可能会发现它已升级到 Ruby 2.5.7,即使您没有明确重新部署。这是 App Engine 的预期行为:它透明地应用关键更新和安全补丁,其中可能包括更新 Ruby 解释器的补丁级别。(请注意,App Engine 仅更新 Ruby 补丁级别。它永远不会将您的应用从 Ruby 2.5 更新到 Ruby 2.6,除非您明确告诉它使用 Ruby 2.6 运行时。)由于此功能,如果您的 Gemfile 指定 Ruby版本,它需要能够处理补丁级别更新,例如通过使用悲观版本约束。

作为辅助说明,在 App Engine 标准环境.ruby-version中被忽略。请注意,这与 App Engine 柔性环境不同,后者使用文件作为您的应用请求特定 Ruby 版本以在其上运行的一种方式。但是,标准环境会为您选择和控制 Ruby 版本,而您没有发言权。

为困境道歉。我将与团队一起努力澄清我们的文档。


推荐阅读