Most of us use Resque and the Resque or Rufus schedulers to schedule tasks in an effective, controlled manner. However, we sometimes need to schedule jobs on machines that don’t have a queue installed. We then have to fall back on good ol’ raw Cron scheduling. The problem here is that Cron jobs usually run under the root user’s environment, which means that the RVM environment variables necessary for running our Ruby script aren’t being loaded, so the Cron job will fail.  

The solution is to explicitly load the RVM environment in the cron user’s context, before we can invoke our Ruby code. Luckily, RVM provides environment files for each configuration, that we can use to load the right context. These files are essentially a list of exported env variables that point to the right locations for the selected Ruby and gemsets.

First, find the RVM environment file for your ruby version and gemset. You can do so by running:

$> rvm env --path -- 2.4.3@my_gemset
home/admin/.rvm/environments/ruby-2.4.3@my_gemset

Then, create a shell script (let’s call it loader.sh) that does the following:

  • sources the RVM environment file
  • runs “bundle install” 
  • calls your Ruby script.  
#!/usr/bin/env bash

source /home/admin/.rvm/environments/ruby-2.1.5@my_gemset
bundle install
ruby /path_to/my_app.rb

Finally, run $> crontab -e and add a line to invoke your shell script, e.g.

1 0 * * sun /path/to/loader.sh

​Your Ruby script should now run at 1 minute past midnight every Sunday. :)