0

Using the default app.yaml configuration provided by Google for Google App Engine Ruby 2.5 standard environment, I cannot deploy successfully when using Rails. If I use Ruby 2.5.5 locally, and in my .ruby-version and Gemfile, the deploy fails with:

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

If I use Ruby 2.5.7 locally and in my Gemfile and .ruby-version file, the deploy succeeds, but visiting the app results in the following error in the logs:

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

And note that I have properly set up .gcloudignore to include .ruby-version and other important dotfiles that are ignored by default by app engine.

Quite the predicament!

You can reproduce my build with this repo: https://github.com/sam0x17/ruby_standard_environment_version_issue

Sam Johnson
  • 624
  • 1
  • 7
  • 20
  • Following a [guide](https://cloud.google.com/appengine/docs/standard/ruby/quickstart) from the GCP documentation, I was able to successfully deploy a simple Ruby 2.5.7 app on GAE Standard. Remember that specifying `runtime: ruby25` in your **app.yaml** file will make your Ruby 2.5 runtime environment use the latest stable [release](https://www.ruby-lang.org/en/downloads/) of Ruby 2.5 (which is currently 2.5.7). – Deniss T. Nov 13 '19 at 15:52
  • Please add a minimal reproducible code to your question, including the content of your **app.yaml** and **Gemfile**. – Deniss T. Nov 13 '19 at 15:54
  • @DenisT. added :) – Sam Johnson Nov 13 '19 at 17:46
  • Note that I have no issues deploying the simple sinatra app provided by the guide. Thus far I have not been able to get the same or similar setups to work with Rails, however. – Sam Johnson Nov 13 '19 at 17:48
  • 1
    Try using `ruby "~> 2.5.5"` in your Gemfile instead of a specific patchlevel like `ruby "2.5.5"`. I think that will unblock you and let you deploy successfully. It looks to me like the builder (which installs your gems and builds the application image) is running 2.5.7, but the runtime is still on 2.5.5. Which shouldn't be happening. (I'll make some inquiries internally and see if I can determine why this would happen.) – Daniel Azuma Nov 14 '19 at 00:45
  • That sounds like it might be exactly the problem, I'll try and get back to you – Sam Johnson Nov 14 '19 at 03:38

2 Answers2

2

Here's the official word from the Ruby App Engine runtime team.

If you have a Ruby version constraint in your Gemfile, always use a pessimistic version constraint (or other mechanism to allow more recent patchlevels), rather than locking to a specific patchlevel. For example, use something like ruby "~> 2.5.5" to indicate 2.5.5 or any newer patchlevel, rather than ruby "2.5.5" or ruby "2.5.7". This isn't a temporary workaround, but an actual requirement and best practice for App Engine standard.

The reason is twofold. During a rollout of a new Ruby version, there may be a short period where the bundle install is run on a different Ruby patchlevel than the app itself. This is what you ran into, and it apparently is the expected behavior because the "bundle builder" component is rolled out independently from the runtime image.

But more importantly, App Engine standard may upgrade your Ruby patchlevel at any time. Your app might be running on Ruby 2.5.6 today, but tomorrow you might find it upgraded to Ruby 2.5.7, even if you didn't redeploy explicitly. This is App Engine's intended behavior: it transparently applies critical updates and security patches, and that may include updating the patchlevel of the Ruby interpreter. (Note that App Engine only updates the Ruby patchlevel. It will never update your app from, say, Ruby 2.5 to Ruby 2.6 unless you explicitly tell it to use a Ruby 2.6 runtime.) Because of this feature, if your Gemfile specifies the Ruby version, it needs to be able to handle patchlevel updates, for example by using a pessimistic version constraint.

As a secondary note, .ruby-version is ignored on App Engine standard environment. Note this is different from App Engine flexible environment, which uses the file as a way for your app to request a specific Ruby version to run on. The standard environment, however, chooses and controls the Ruby version for you, and you don't get a say.

Apologies for the predicament. I'll work with the team to try to clarify our documentation on this.

Daniel Azuma
  • 829
  • 7
  • 9
0

As per Daniel Azuma's comment, it looks like changing the version constraint for ruby in my Gemfile to ruby "~> 2.5.5" fixes the issue. My understanding is in the future this will no longer be necessary, but for now this is the workaround.

Sam Johnson
  • 624
  • 1
  • 7
  • 20