After deploying an Application, I have to at times do repetitive things like running a rake job, mailing me the log file, clearing the logs, sending newsletter every friday, etc. These are basically some commands I have to run on a regular basis. Running them manually for sometime is great as it allows us to iron out all the errors, but after it stabilizes, there is no reason for us to be doing it manually again and again.
What we need is a way to automate these tasks, which needs to be triggered at specific amounts of time. The most common way of doing this is to use cron, which is available on most UNIX-based (Linux, Mac for example) systems.
If you are a Unix expert, you might have used cron by editing cron files. To edit them, we simply run the command
$ crontab -e
and write the commands in the file that opens. Syntax is a bit tricky but main problem occurs when you start deploying to multiple servers. You would need to write cron file on every server again and update everywhere when necessary.
Enter, whenever ruby gem! It’s the perfect solution for Rails based applications where you need to use cron.
For example, if I want to run a rake task which sends mail every monday at 7:30 AM, I’ll need to write
every :monday, :at => "7:30 am" do rake "send_mail:newsletter" end
This looks so much better than the cron commands, it scores high on readability points and is easier to remember and change.
The thing I want to discuss are the issues I faced when my development environment was windows and deployment, Ubuntu!
The very first thing you need to do is set your output to a log file. I had put my output in log/cron.log under my Rails directory.
To do this, write
set :output, 'log/cron.log'
config/schedule.rb file. This way, all the output from Cron tasks will be shown in
Now, the very first problem I faced was it couldn’t find
bin/bash. I tried searching on the internet but couldn’t find it. Later, I realized that
.exe extension works in windows and not in Ubuntu.
To solve this problem, I opened the file
bin/rails and saw
written on the very first line there. I immediately removed the .exe extension, commited the repo there and the problem was solved.
By the way, to run open rails console in some other environment, like production, you’d need to write
RAILS_ENV=production rails c to make it work. Somehow,
rails c RAILS_ENV=production doesn’t work.
At this point, everything was working properly until I deployed my application again. This time, the cron output gave errors about how the rails file was not executable. I later realized that this may be because when I do a
git pull, the files in
bin folder become read-write and not executable.
This is easy! We just need to do
chmod +x bin/rails to make it work. Unfortunately, this wasn’t enough as I forgot to do this every time I pulled from my repo onto the server.
Thus, I added a
command type cron job. I wrote in my
command "chmod +x path/to/app/root/bin/rails"
And had it run at 6 in the morning so my jobs, scheduled for 8 AM, 10 AM and 12 AM work without a glitch!
Yup, scheduling jobs is that easy.
Don’t forget to write
whenever --update-crontab aap-name to write to cron file. Add it to your
capistrano‘s after deploy. You can also add
chmod +x execution to
capistrano‘s after deploy. Comment out how you used it.
Also, do let me know if you’ve been able to deploy to your VPS while developing on Windows and using
capistrano to deploy.