Specifying a Ruby Version
Last updated December 02, 2024
Table of Contents
Selecting a version of Ruby
You’ll need to install bundler 1.2.x
or above to use the ruby
keyword and bundler 1.13.x
or above to use a Ruby version specifier.
You can use the ruby
keyword in your app’s Gemfile
to specify a specific version of Ruby.
source "https://rubygems.org"
ruby "3.2.2"
# ...
Heroku recommends you run the latest Ruby version your app can handle. Ruby 3.2.2 might not be the latest Ruby version, and is here for demonstration purposes only. For an updated list see Supported Ruby Versions.
When you commit and push to Heroku you’ll see that Ruby 3.2.2
is detected:
-----> Heroku receiving push
-----> Ruby/Rack app detected
-----> Using Ruby version: 3.2.2
-----> Installing dependencies using Bundler version 2.5.6
...
For specifying non MRI Ruby engines, you’ll need to use the :engine
and :engine_version
options. You can specify JRuby by using the following line:
ruby "2.2.2", :engine => "jruby", :engine_version => "9.0.0.0"
Please see Ruby Support for a list of available versions.
Ruby Version Specifiers
As of bundler 1.12
+, you can use a version specifier in your Ruby version. For example, if you want to deploy using 3.2.2
but some members of your team want to use 3.2.3
, you can do this by specifying:
ruby "~> 3.2.2"
This is saying that any version of 3.2.x
where x is greater than or equal to 2 is valid. For this to work on Heroku, you must specify the full version with all three digits. For example, ~> 3.2
and ~> 3.2.x
aren’t valid version specifiers on Heroku.
Bundler locks the Ruby version you’re using locally in the Gemfile.lock
. In the above scenario, if someone with Ruby 3.2.1
on their system runs bundle install
then they get the following in the Gemfile.lock:
RUBY VERSION
ruby 3.2.2p53
To update this version in the Gemfile.lock
, change your local Ruby version, ensure you have a ruby
declaration in your Gemfile
and run:
$ bundle update --ruby
The locked version of the Ruby version will always “win”. So if different members on your team are using different Ruby versions, they must be careful not to commit the wrong version to the Gemfile.lock
.
If you ever have doubts about the version that Heroku will use you can find out by running this command locally:
$ bundle platform --ruby
Specifying a Ruby version via the environment
If you’re using Bundler 2.3 or earlier, you can set your Ruby version using an environment variable. A Gemfile
is made of up Ruby code, so you can also specify your Ruby version in the environment. For example:
ruby ENV['CUSTOM_RUBY_VERSION'] || '2.5.1'
Changing environment variables does not recompile your app. For a Ruby version change to take effect through this method, you’ll need to deploy the app again since Ruby is vendored into each slug.
This would let you specify a Ruby version in the CUSTOM_RUBY_VERSION
environment variable, or default to 2.5.1
if it’s not set. This is handy if you are running your app through a continuous integration tool and want to ensure it checks your codebase against other versions of Ruby, but restrict it to a certain version when deployed to Heroku.
We recommend limiting use of environment variables in your Gemfile
and we do not recommend using conditionals. If you need to configure things such as usernames or passwords for private repos, please see bundler configuration.
Troubleshooting
I specified a Ruby version in my Gemfile but Heroku installed a different one
Starting with Bundler 2.4+, bundler no longer emits a Ruby version if it’s not locked in the Gemfile.lock
. To ensure Heroku can read your Ruby version, run the following command locally:
$ bundle platform --ruby
If you see an output like No ruby version specified
you might need to lock your version in your Gemfile.lock
with the following commands:
$ bundle update --ruby
$ git add Gemfile.lock
$ git commit -m "update ruby version"
Your Ruby version is <X>, but your Gemfile specified <Y>
The most common cause of this error is the Gemfile.lock
was not updated after you modified your Gemfile
. To fix this please run
$ bundle update --ruby
$ git add Gemfile.lock
$ git commit -m "update ruby version"
If you are still getting an error saying that your ruby version is different than the current version specified, there are several possible causes.
First, verify that you’re using a recent version of bundler locally. We recommend running at least the same version as Heroku. You can see the version locally by running:
$ bundler -v
Bundler version 1.13.6
Once you’ve verified you’re using a recent version of bundler, verify the version you’ve specified on your app by running.
$ bundle platform --ruby
ruby 2.3.3p222
If this is not what you expect it to be, check inside of your Gemfile.lock
:
$ cat Gemfile.lock | grep -A 2 RUBY
RUBY VERSION
ruby 2.3.3p222
This is the version that bundler will prefer. If it is not what you want, run bundle install
locally and it will set your Gemfile.lock
ruby version to what ever you are running locally.
If when you push to Heroku, you are still getting that error make sure that you’ve committed your changes to git
$ git add Gemfile.lock
$ git commit -m "Gemfile.lock ruby version"
Also verify that you’re on the master
branch of your project
$ git status -b
On branch master
If you’re on a different branch than master when you run git push heroku master
this command is shortcut for git push heroku master:master
which means to send the master of your local repo to the master branch of Heroku. If you wanted to deploy a non-master branch such as testing-feature-1
you would have to execute git push heroku testing-feature-1:master
.
A way to avoid this confusion is to set up Heroku review apps and to have a Continuous Integration (CI) server deploy to Heroku when commits are merged to master.
Migration
Applications that migrate to a non-default version of Ruby should have bin
be the first entry in their PATH
config var. The Ruby buildpack sets this value and you should not modify it. This var’s current value can be determined using heroku config
.
$ heroku run bash
$ env | grep PATH
PATH=/app/bin:/app/vendor/bundle/bin:/app/vendor/bundle/ruby/2.2.0/bin:bin:vendor/bundle/ruby/1.9.1/bin:/usr/local/bin:/usr/bin:/bin```
If absent or not the first entry you should ensure you’re using the supported version of the Ruby buildpack. If you are, please open a support ticket.
If the PATH
is set correctly you will see the expected version using heroku run
:
$ heroku run "ruby -v"
Running `ruby -v` attached to terminal... up, run.1
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
If the PATH
is not setup correctly, you might see this error:
Your Ruby version is 1.9.2, but your Gemfile specified 1.9.3
If your PATH is setup correctly you may get this error if you have an improper hashbang (#!) line committed. For example in bin/bundle
starts with this:
#!/usr/bin/env ruby1.9.1
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
load Gem.bin_path('bundler', 'bundle')
It will attempt to use the wrong version of Ruby. Make sure your first line does not specify a version like this:
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
load Gem.bin_path('bundler', 'bundle')
Bundler Errors
If you’re using a Bundler 1.1.4
or lower you’ll see the following error:
undefined method `ruby' for #<Bundler::Dsl:0x0000000250acb0> (NoMethodError)
You’ll need to install bundler 1.2.0
or greater to use the ruby
keyword.
$ gem install bundler