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.
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
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!
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 😞
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 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.
Where can you find the source code for the build script so that I can debug how to set the ruby version?
I put parndt’s build script into the build settings and saw it install ruby 3.1.0 perfectly fine, but then it still tried to use ruby 2.6 (which I think is EOL?)
#!/usr/bin/env bash
# exit on error
set -o errexit
# Use the correct version of Ruby
source $RENDER_SRC_ROOT/web/bin/render/env.sh
gem install bundler --silent
gem update --system --silent --no-document
bundle install
npm install --prefix $RENDER_SRC_ROOT/web
npm run build --prefix $RENDER_SRC_ROOT/web
bin/render/start.sh:
#!/usr/bin/env bash
# exit on error
set -o errexit
# Use the correct version of Ruby
source $RENDER_SRC_ROOT/web/bin/render/env.sh
cd $RENDER_SRC_ROOT/web
bin/puma
bin/puma is just the binstub that is generated with bundle binstubs puma.
Sure! If you’re dealing with multiple apps in a monorepo on Render and need different Ruby versions, it can be tricky because Render picks up the Ruby version from a single .ruby-version file in the root of your repo. Here are some ways to handle it:
Use Docker: Create Dockerfiles for each app with the desired Ruby version specified. Render supports deploying Docker containers, giving you control over the environment.
Environment Variables/Configuration: Set up each app to read the required Ruby version from environment variables or configuration files. Adjust the app’s behavior based on this information.