The Ruby on Rails and ClojureScript experts

Mar 30, 2009

For simple applications I use cron to run automated background jobs like sending emails or indexing sphinx.

I like to have all aspects of my application under version control. Cron is no exception. To do this, I add a file named “crontab” in /config. In there I add all my cron jobs in regular cron notation.

Then I add something like this to my capistrano deploy recipe:

task :after_update_code, :roles => :app do
  # Install crontab
  # IMPORTANT: works only if this is the only instance of app
  # running under this user account
  run "crontab -u #{user} #{release_path}/config/crontab"
end

Now every time I deploy, capistrano updates the deploy user’s crontab with the most current version.

When it doesn’t work as expected…

… here are the places to look:

First run the cron command on the command line. Run it as the same user as cron would run it. I typically use my deploy user to do everything: web server user, capistrano user, ssh user, cron user. This helps avoid issues with permissions. I also keep the app in the deploy user’s home directory.

If the command executes fine on the command line, however it doesn’t from cron, then there is a good chance that you have differences in PATH or SHELL between cron and command line. To address this, set both in the crontab:

PATH=(your path...)
SHELL=(your shell...)

To find out your deploy user’s PATH and SHELL run these two commands as deploy user on the production server’s command line:

echo $PATH
echo $SHELL