Allow Ruby version to be specified per app

Hi,

I’m working with a monorepo where two or more apps (all hosted on Render) sometimes have to use different versions of Ruby.

Unfortunately, Render guesses the Ruby version based on a .ruby-version file that we have to put in the root of our monorepo, but this means that I can’t use a different version of Ruby. I’ve tried setting variables like DEFAULT_RUBY_VERSION etc but these don’t work.

Is there a way to achieve what I’m trying? Do I have to do something like Specify NPM version? - #3 by sonny ?

Ideally, we’d have RUBY_VERSION supported like NODE_VERSION is here Specifying a Node Version | Render

Edit: I’ve just requested a feature here Specify Ruby version | Feature Requests | Render

Thanks!

Hi @parndt, thank you for submitting that feature request, that is a great suggestion!

One possible workaround I can think of is to have multiple Gemfiles in the root of your project with different Ruby versions and respective names i.e. Gemfile-2.2.4, Gemfile-2.2.5 etc.

Then, create multiple build scripts i.e. bin/build-1.sh, bin/build-2.sh. In those scripts you can then specify which Gemfile to use with Bundler’s --gemfile flag

So bin/build-1.sh might look like this:

#!/usr/bin/env bash
# exit on error
set -o errexit

bundle install --gemfile="Gemfile-2.2.4"
bundle exec rake assets:precompile
bundle exec rake assets:clean
bundle exec rake db:migrate

Then in the settings for your Render app you would specify which build script to use for each respective app. Keep in mind I haven’t tried this myself but it might be a temporary solution!

Hi Tyler,

Unfortunately not, what we see instead is:

Aug 12 08:54:38 AM  ==> Downloading cache...
Aug 12 08:54:48 AM  ==> Downloaded 121MB in 4s. Extraction took 4s.
Aug 12 08:54:56 AM  Updating rubygems-update
Aug 12 08:54:56 AM  Successfully installed rubygems-update-3.2.25
Aug 12 08:54:56 AM  Installing RubyGems 3.2.25
Aug 12 08:54:56 AM  ERROR:  While executing gem ... (Errno::EROFS)
Aug 12 08:54:56 AM      Read-only file system @ dir_s_mkdir - /usr/local/lib/ruby/site_ruby/2.6.0/rubygems
Aug 12 08:54:57 AM  ==> Running build command 'bundle install --gemfile="Gemfile-web"'...
Aug 12 08:54:57 AM  Your Ruby version is 2.6.5, but your Gemfile specified 3.0.2
Aug 12 08:54:57 AM  ==> Build failed 😞

Thanks,
Phil

Hmm, do you still have the .ruby-version file? If you do, can you try removing that so it will force our code to look in the Gemfile for the version?

Nope, unfortunately not:

Aug 12 10:54:24 AM  ==> Downloading cache...
Aug 12 10:54:28 AM  ==> Downloaded 33MB in 2s. Extraction took 1s.
Aug 12 10:54:31 AM  ==> Running build command './bin/build-web.sh'...
Aug 12 10:54:31 AM  Your Ruby version is 2.6.5, but your Gemfile specified 3.0.2
Aug 12 10:54:31 AM  ==> Build failed 😞

If I had to hazard a guess, I’d say it comes from this part of your build scripts:

DEFAULT_RUBY_VERSION=2.6.5

and further on:

local detected_version='';
 local rv="${RENDER_SRC_ROOT:-.}/.ruby-version";
 if [[ -f $rv ]]; then
 detected_version=$(head -1 "$rv");
 fi;
 local gemfile="${RENDER_SRC_ROOT:-.}/Gemfile";
 if [[ -z $detected_version && -f $gemfile ]]; then
 detected_version=$(version_from_gemfile "$gemfile");
 fi;
 if [[ -z $detected_version ]]; then
 detected_version=$DEFAULT_RUBY_VERSION;
 fi;

It first looks for a .ruby-version and then it looks for a file called exactly Gemfile. Here would be a great place to first look for a $RUBY_VERSION, right above trying the .ruby-version file:

local rv="${RENDER_SRC_ROOT:-.}/.ruby-version";

The first thing I tried was overriding DEFAULT_RUBY_VERSION with an environment variable with value of 3.0.2, as well as setting RUBY_VERSION to 3.0.2 and RUBY_MAJOR to 3.0 but it doesn’t seem to respect it, or maybe by then it is too late? My investigation stopped here because I can’t override RENDER_PRE_BUILD_CMD :innocent: and I think that it’s all happening before I can do anything about it.

I’m currently trying another approach where I take more control in the build and start scripts, and I’ll report back.

Of course it would be a lot easier to be able to set RUBY_VERSION and have that override all of the auto-detection.

Hope that helps!

I got it working.

I created a build.sh and a start.sh for this sub-project called web in the monorepo:

build.sh:

#!/usr/bin/env bash
# exit on error
set -o errexit

export RUBY_VERSION=$(cat $RENDER_SRC_ROOT/web/.ruby-version)
export BUNDLE_GEMFILE=$RENDER_SRC_ROOT/web/Gemfile
set_ruby_env $(fetch_or_build "$RUBY_VERSION")
gem install bundler
gem update --system
bundle install

start.sh

#!/usr/bin/env bash
# exit on error
set -o errexit

export RUBY_VERSION=$(cat $RENDER_SRC_ROOT/web/.ruby-version)
export BUNDLE_GEMFILE=$RENDER_SRC_ROOT/web/Gemfile
source /home/render/ruby-env.sh
set_ruby_env "$RUBIES_ROOT/ruby-$RUBY_VERSION"

cd $RENDER_SRC_ROOT/web
bundle exec puma -C ./config/puma.rb

At least it works now, even if it is just a workaround.

Phil