Rake Task from Crontab? - ruby-on-rails

Stack:
Apache2
Rails 2.3.8
RedHat Linux
Ruby Enterprise 1.8.7
Got the following rake task in my app user's crontab which is meant to pull records into a database table every 15 min:
*/15 * * * * app_user cd /var/www/apps/my_app/current/ && rake thing:do_stuff RAILS_ENV=production
I can see that the cron daemon is running this task in the cron log, but the database table it's supposed to pull records into doesn't change. This task is working without error when I run it manually in the /var/www/apps/my_app/current directory, and pulls records into the table as I expect it to.
I reset the PATH variable in the crontab to reflect using REE, thinking maybe the default path wouldn't jive with /opt/ruby-enterprise...
How do I get this rake task to actually run with cron?

0,15,30,45 * * * * /bin/bash -l -c 'cd /var/www/apps/my_app/current && RAILS_ENV=production bundle exec rake thing:do_stuff --silent'

Try to use full path to rake binary (run in console which rake and replace rake with full path).
For example, if which rake returns the following path:
/Users/bob/.rvm/gems/ruby-1.9.3-p194/bin/rake
You should use the following command to run the rake task:
/Users/bob/.rvm/bin/rvm all do bundle exec rake allocator:snapshot
and I prefer whenever gem for cron jobs in ruby
How to detect if task failed in cron? On fail cron tries to send email. So you can configure postfix to use your smtp settings (from google for example), and add file ~/.forward containing only your email to home directory of user who is running that cronjob in your system.

Related

Blazer gem: Scheduled rake tasks not working automatically but work fine when invoked from console

I have set up a couple of rake tasks to run automatically with the whenever gem . The tasks involve running a background Job, performing a database Blazer check and sending failing checks emails.
The last two are provided by the Blazer gem.
This is my schedule.rb file:
set :environment, "development"
every 1.minutes do
rake "health_check:perform"
end
every 1.minutes do
rake 'blazer:run_checks'
end
every 2.minutes do
rake "blazer:send_failing_checks"
end
The "health_check:perform" rake task always performs as expected, and I can see the Job being run in my server log every minute.
The other two, however, don't seem to be executing at all.
I can tell blazer:run_checks is not executing because when a Blazer check is run either manually or automatically, the blazer_checks table last_run_at column value is updated with the timestamp when the last check was run. Also, I can see the update DB transaction in my server log when that happens.
On the other hand "blazer:send_failing_checks" is not working either because well, no emails are ever delivered.
However, if I manually invoke the task from my console via rake "blazer:run_checks" or rake "blazer:send_failing_checks" they perform normally (blazer_checks table is updated and failing check emails are delivered).
I can't spot any error messages in my server log, altough I believe by default rake tasks are set to run in silent mode? Since running whenever -l to list my crontab file returns something like:
* * * * * /bin/bash -l -c 'cd /home/user/code/myapp && RAILS_ENV=development bundle exec rake health_check:perform --silent'
* * * * * /bin/bash -l -c 'cd /home/user/code/myapp && RAILS_ENV=development bundle exec rake blazer:run_checks --silent'
0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58 * * * * /bin/bash -l -c 'cd /home/user/code/myapp && RAILS_ENV=development bundle exec rake blazer:send_failing_checks --silent'
Any ideas? How can I debug this?

Cronjobs for Rails stopped working after switching to asdf

I recently changed from rvm to asdf.
Since then, I can't get cronjobs to run.
crontab -l
* * * * * /bin/bash -l -c 'cd /var/www/jobs/code && RAILS_ENV=production bundle exec rake cron_test' >> /tmp/cron_test_output 2>&1 /tmp/cron_error
gives me /tmp/cron_error: bundle: command not found. There is no output to stderr.
gem install bundler has not worked for the jobs user.
Not sure where to install bundler to make this work.
The rake tasks work when run independently. The cronjobs that are not rake tasks run. Cron is working.
Edit:
While the cronjobs were working before, they obviously can't now find the location of bundler. By changing bundle exec to the full path /home/jobs/.asdf/shims/bundler exec, I have managed to get this to work.
I have been using the whenever gem to create cron jobs for rake tasks. Turns out the easiest way to get around this problem is to make sure that the environment path is included in the whenever generated crontab.
within config/schedule.rb for the whenever gem, I added the following:
env :PATH, ENV['PATH']
and now everything is working as the cron job can now find the bundler.
Based on this issue from the whenever gem.
And this one too.

How can I run a rake task via cron?

I have and rails application and a rake task which I'm going to execute by cron around once in an hour. But the thing is that the task uses rails environment and some classes of my rails application. If I run it as ruby script, I'll have to include all the dependencies it uses and I think it's not possible to do it correctly and in a simple way. So I'll have to run it as a rake task because it'll preserve all the dependencies, right? Then how can I run a rake task from cron?
Note that I prefer not to use any third-party solution when there's no necessity, in this case I don't want to use the gem whenever or the like.
You can add to your crontab something like
0 * * * * /bin/bash -l -c 'cd /path/to/your/project && bundle exec rake foo:bar >> log/cron.log 2>&1'
This will run foo:bar task every hour and write stdout and stderr to log/cron.log.
Please notice bundle exec before rake command.
Using bundler ensure you that task will fetch correct environment.
To specify RAILS_ENV you can do
... && RAILS_ENV=production bundle exec rake foo:bar
Use whenever to simplify your life https://github.com/javan/whenever ;)
Here's an example of a rake task:
task :foo => :environment do
puts "Running rake task in environment: #{Rails.env}"
# can access Models here or whatever
end
Note that the => :environment part is optional, but it what makes your Rails environment to the task block.
You can put rake run_my_task in your cron job.
You may need to use something like cd /home/$USER/my_rails app && rake run_my_task to ensure that the cron runs the task from the Rails root directory.

How to run a rake task regularly with using CRON?

I've written a rake task for my Rails application and I'd need to run this tasks regularly with using CRON.
If I have a URL that I need to ping with CRON, I do it like this:
0 */6 * * * curl https://www.website.com/something
But how to "ping" a rake task?
The application is located in /home/deployer/apps/myapp-production/current and is running on DigitalOceal (Ubuntu server - nginx).
Thanks.
EDIT: This is my command:
0 */6 * * * cd /home/deployer/apps/myapp-production/current && RAILS_ENV=production bundle exec rake db:backup
But the output is:
/bin/sh: 1: bundle: not found
When I run just rake db:backup on my laptop (locally), everything works just well.
Do I have incorrect the path in the CRON task?
EDIT2: When I run the command cd /home/deployer/apps/myapp-production/current && RAILS_ENV=production bundle exec rake db:backup manually from the command line, everything is working, but not from the CRON.
Use whenever gem. It provides nice DSL like:
every :day, :at => '12:20am', :roles => [:app] do
rake "app_server:task"
end

Running RAILS_ENV=production with the system command

I have got a really weird problem with a script that I am running on my server, the details are below. But essentially I am using a script to set up a rails application and I am calling that script from an existing rails application.
In my existing application (the application that is calling the script on the server) I have:-
Spawnling.new do
system "cd ~/ && ~/*/create_site.sh param1 param2 >> /tmp/logger"
end
The create_site.sh script creates a fresh installation of rails using the below:
rails new $DIR --database postgresql
It then does a number of things to set up the application. The issue is that the script seems to run absolutely fine until it gets to the following command:
cd $DIR && RAILS_ENV=production rails g roroacms:install -v && RAILS_ENV=production rake assets:clean && RAILS_ENV=production rake assets:precompile
It is really odd because when I run the top command manually as the root user it seems to run absolutely fine without any issues at all. When I view the logger file at the end of the top command it looks like the below:
Your bundle is updated!
Bundle is installed and up to date
RoroaCMS installation
Installation complete with assets
Server started
When I run this manually it outputs a number of messages between each line where it is running the command. Any ideas on this? I am thinking that it could be something to do with RAILS_ENV as the rails new command runs fine earlier in the script.
Hi I do a fair bit of scripting rails on servers and I always use the format bundle exec rails g rspec:install production so your command would be cd $DIR && bundle exec rails g roroacms:install -v production && bundle exec rake assets:clean production && bundle exec rake assets:precompile production. I dont have a whole lot of reasoning behind it but that format seems to be most reliable across different server environments.

Resources