David - Musings of an SRE

Whenever - Easy Cronnable Rake Tasks! With Capistrano!

We all have this problem before.

Attempting to write a crontab that runs a rake task is almost a painful endeavor. Especially if you’re running a ruby version manager like RVM.

Luckily, this crontab DSL gem, “Whenever”, created by Javan, helps make things so much easier.

To get started, make sure you have whenever in your Gemfile:

#Gemfile
gem 'whenever'

Then, run wheneverize:

/home/myapp$ wheneverize .

This will create your config/scheduler.rb file which will contain all your scheduled tasks that you want to cron.

An example from the whenever README.md:

every :day, :at => '1:37pm', :roles => [:app] do
  rake 'app:task' # will only be added to crontabs of :app servers
end

every :hour, :roles => [:db] do
  rake 'db:task' # will only be added to crontabs of :db servers
end

every :day, :at => '12:02am' do
  command "run_this_everywhere" # will be deployed to :db and :app servers
end

Once that is done, lets test it out!

Run,

$ whenever

You should see a copy-and-pasteable crontab script ready for you to insert into your crontab manually.

Note: whenever doesn’t save the output directly into crontab unless you explicitly tell it to. do a ‘whenever –help’ for a list of available commands.

So obviously, at this stage, whenever is nothing more than a parser. Turning ruby code into a useable cron script.

How can we automate this?

If you’re using Capistrano, the folks already have a whenever/capistrano recipe included.

In your config/deploy.rb,

  1. Add the require
require 'whenever/capistrano'
  1. If you’re using RVM, you need to make sure that whenever is run with bundler. Add the following,
set :whenever_command, 'bundle exec whenever'
  1. Now, look at the recipe and see what command that you’d like to use.

  2. In my case, I want the crontab to be updated whenever I have make changes to my code, so I add the following in my after deploy:update_code callback.

after 'deploy:update_code','whenever:update_crontab'
  1. Deploy away! After a successful deploy, you should see the remote user’s crontab -e being modified with the DSL output code.

Enjoy!