RVM + Rake tasks on Cron jobs ~ Aug 2, 2011
RVM hates my guts. And it doesn't matter, because I hate RVM back even more. Since I was technologically raised by aging wolfs, I have strong reasons to believe that you just shouldn't have mixed versions of software on your production systems, specially, if a lot of things are poorly tested, like most of Ruby libraries, aren't backward compatible. I was raised on a world where everything worked greatly because the good folks at projects like Debian or Perl have some of the greatest QA processes of all time, hands down. So, when someone introduces a thing like RVM which not only promotes having hundreds of different versions of the same software, both on development, testing and production environments, but also encourages poor quality looking back and looking forward, there isn't anything else but to lose faith in humanity.
But enough for ranting.
I had to deliver this side project that works with the Twitter API and the only requirement pretty much was that it had to be both run from the shell but also loaded as a class within a Ruby script. And so I did everything locally with my great local installation of Ruby 1.8.7. When it came the time to load on the testing/production server I found myself on a situation where pathetic RVM was installed. After spending hours trying to accommodate my changes to run properly with Ruby 1.9.2, I set up a cron job using crontab to run my shit every now and then. And the shit wasn't even running properly. Basically, my crontab line looked something like this:
*/30 * * * * cd /home/david/myproject && rake awesome_task
And that was failing, crontab was returning some crazy shit like "Ruby and/or RubyGems cannot find the rake gem". Seriously? Then I thought, well, maybe my environment needs to be loaded and whatever, so I made a bash script with something like this:
#!/bin/bash cd /home/david/myproject /full/path/to/rvm/bin/rake -f Rakefile awesome_task
And that was still failing with the same error. So after trying to find out how cron jobs and crontab load Bash source files, I took a look at how Debian starts its shell upon login. And while that didn't tell me that much that I didn't know, I went to look at the system-wide /etc/profile and found a gem, a wonderful directory /etc/profile.d/ where a single shitty file was sitting, smiling back at me, like waiting for me to find it out and swear on all problems in life: rvm.sh. /etc/profile is not being loaded when I just run /bin/bash by my crappy script, only when I log in, I should've known this. Doesn't RVM solve the issue of having system-wide installations so the user doesn't have to deal with, you know, anything outside of his own /home ?
So I had to go ahead and do:
#!/bin/bash source /etc/profile cd /home/david/myproject /full/path/to/rvm/bin/rake -f Rakefile awesome_task
And hours later I was able to continue with work. Maybe this will help some poor bastard like myself on similar situation on the future.
Of course one can argue that I could've installed my own RVM and its Ruby versions, but why, oh why, if it was, apparently, already there. Why would I have to fiddle with the Ruby installations if all I want is get my shit done and head to City Bakery where I can spend that money I just earned on chocolate cookies? My work is pretty simple to run with pretty much any ancient version of Ruby, nothing fancy (unless you call MongoMapper fancy). RVM is a great project that doesn't solve an issue, but just hides some really fucked up shit on the Ruby community.


Hello!
Interesting, I'm struggling to some similar shit.
Could you please tell me, where do you check for crontab errors ?
and, Where do you put these lines:
#!/bin/bash
source /etc/profile
cd /home/david/myproject
/full/path/to/rvm/bin/rake -f Rakefile awesome_task
?
and another thing: I thought I have to do this:
# crontab -e
*/ * * * * /home/jose/work/App/lib/tasks/rake videos:destroy_all
What's wrong with this?
Thanks
jose
3 Aug 11 at 12:44 pm
Well. Usually crontab will dump STDERR and STDOUT output through your local mail delivery. So, unless you redirect that output somewhere else, you should just get it by running 'mail' or 'mutt', since both should read from /var/mail or depending on your mail system, Sendmail, Postfix, Exim, etc.
Where do I put those lines? On a /any/path/to/script.sh and then run that script directly from the crontab line.
Your crontab line is fucked up because of the "*/". When you're adding slashes means "every X". If it's on the first location, which is the minute, "*/5" will mean every minute. Go read a crontab manual.
Hope that helps.
David Moreno
3 Aug 11 at 3:25 pm
OMG, this is the best blog post ever. And only partially because it fixed my cron-rake-rvm problem.
Shelly Roche
23 Aug 11 at 5:12 pm
Holy crap, I just ran into this myself. I had cronjobs that were supposed to run rake tasks, instead they did this: "/bin/bash: rake: command not found"
So the trouble is that none of RVM's magic gets loaded up for non-login shells? This would seem to be because the RVM setup gets done from /etc/profile (for "system-wide" rvm install) or ~/.bash_profile. I'm thinking it should be in /etc/bashrc and/or ~/.bashrc
chuck
2 Dec 11 at 12:55 pm
I just put this in /etc/bashrc, will let you know if it helps:
. /etc/profile.d/rvm.sh
chuck
2 Dec 11 at 12:58 pm
That seems not to have done the trick. Lame.
chuck
3 Dec 11 at 8:30 pm
Thanks for the post! I was able to get this down to one line in crontab.
*/30 * * * * source /etc/profile && /usr/local/rvm/gems/ruby-1.9.3-p0/bin/rake –rakefile /path/to/rails/Rakefile awesome_task RAILS_ENV=production
Remo
12 Dec 11 at 9:41 am
City Bakery is the greatest!
Dan
15 Feb 12 at 12:14 pm
I so want to kiss you for this post!
But I want, so thanks
Piotrek
27 Mar 12 at 8:56 am