Making RVM play nicely with system scripts

August 5, 2013 cron initscripts Ruby RVM server configuration

Situation: you have a Ruby app, which uses RVM and specifies its Ruby version with a .ruby-version file. You want to use that app in a system script, such as, a Cron job, or start from an init.d script, or any other place that’s not a user shell. And it doesn’t work, failing with strange error messages.

I found that the easiest and most reliable way to use RVM Ruby from scripts is to explicitly source rvm:

#!/bin/bash
source /etc/profile.d/rvm.sh
cd /myapp && bundle exec rake

or in a one-liner:

/bin/bash -c 'source /etc/profile.d/rvm.sh; cd /myapp && bundle exec rake'

After you do this, RVM behaves exactly as you would expect, honoring per-directory .ruby-version files. And you don’t need to make wrappers.

There are other solutions to the problem, more or less obscure; some are described in RVM articles about cron and initd scripts.

Also, what’s very important in the case of a system-wide RVM install, you do NOT add unprivileged users to the RVM group. The RVM group is for administration purposes, like updating RVM and Ruby - and it has write permissions all around the RVM directory. Which means, if your app user is compromised, the attacker can inject code into any Ruby runtime, and if your root user uses that runtime (like in some cron jobs), it’s a pretty direct way to obtain root access.

Any user can use system-wide installed RVM without being added to the RVM group.

Buy Me a Coffee at ko-fi.com