I had a problem about set crontab Ubuntu 14.04 on DigitalOcean VPS.
Here are my steps:
First, create new crontab: crontab -e
Second, i set this command:
This is my crontab which i set it run at 10:26AM everyday:
26 10 * * * /bin/bash -l -c 'cd /var/www/my_app/current && RAILS_ENV=production bundle exec rake check:user >> log/cron_log.log'
Third, i checked crontab as crontab -l
Finally, i restart crontab as sudo service cron restart
But it didn't run anyway (i waited for 10:24 until 10:30), and i copied this command and ran it in my console, it worked very well.
So, i didn't understand why it didn't run same as crontab. Hope everybody can explain or give me some advises. Thank you very much.
EDIT: I tried to use gem whenever but it didn't run.
set :environment, "production"
env :PATH, ENV['PATH']
env :GEM_PATH, ENV['GEM_PATH']
set :output, {:error => "log/cron_error_log.log", :standard => "log/cron_log.log"}
# Learn more: http://github.com/javan/whenever
every :day, at: '10:26am' do
rake "check:user"
end
And i updated my crontab use whenever as whenever -w
But it don't work.
Update:
#Coderhs: I tried run this command bundle exec whenever --update-crontab RAILS_ENV=production, but it didn't work :(.
This is list my crontab when i use command crontab -l:
# Begin Whenever generated tasks for: RAILS_ENV=production
PATH=/var/www/my_app/shared/bundle/ruby/2.2.0/bin:/usr/local/rvm/gems/ruby-2.2.1/bin:/usr/local/rvm/gems/ruby-2.2.1#global/bin:/usr/local/rvm/rubies/ruby-2.2.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/rvm/bin
GEM_PATH=""
26 10 * * * /bin/bash -l -c 'cd /var/www/my_app/releases/20150710024713 && RAILS_ENV=production bundle exec rake user:check --silent >> log/cron_log.log 2>> log/cron_error_log.log'
# End Whenever generated tasks for: RAILS_ENV=production
It still didn't run.
UPDATE:
The problem was solved. Because in my local TIME was different with SERVER TIME.
So, i had just set SERVER TIME same as my LOCAL TIME. Thank you everybody supported me.
Like previously mentioned, I would use whenever gem.
Make sure you run whenever -w again after each capistrano deploy so its looking for the correct release directory.
Make sure you run whenever -w as the same user that your application is running as. Don't use root unless your app is running as root, which it shouldn't be.
Also, you should have your log dir set as a shared directory in Capistrano deploy config. Something like this in config/deploy.rb :
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'pids', 'public/uploads', 'public/temp')
Also run the 'date' command in your terminal and see what the time there is. It might not be your local time, so the cron could work but at a totally different time than when you are expecting.
The issue is probably because the user which runs the cron, can't access the ruby command 'bundle'. You will have to use the full bath to the bundle executable file in the crontab.
The better solution for this problem would be to use the whenever gem https://github.com/javan/whenever
It would manage all the stuff related to crontab, to avoid issues like this.
schedule.rb for whenever
set :environment, "production"
set :output, {:error => "log/cron_error_log.log", :standard => "log/cron_log.log"}
env :PATH, ENV['PATH']
env :GEM_PATH, ENV['GEM_PATH']
# Learn more: github.com/javan/whenever
every :day, at: '10:26am' do
rake "check:user"
end
don't forget to run.
bundle exec whenever --update-crontab RAILS_ENV=production
after you set the shedule.rb
Related
I am trying to make a simple cron job running this task:
Here is my schedule.rb:
set :environment, "staging"
set :path, "/var/www/my_app/current"
every 2.minutes do
# specify the task name as a string
rake 'cron_test'
end
Here is the task:
task :cron_test => :environment do
out_file=File.new("cron_test.txt", "w")
out_file.puts(Time.now.to_s)
out_file.close
end
I tried to do what is advised on this page but nothing works:
Cron job not working in Whenever gem
When I run crontab -l :
# Begin Whenever generated tasks for: /var/www/my_app/current/config/schedule.rb
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 /var/www/my_app/current && RAILS_ENV=staging bundle exec rake cron_test'
# End Whenever generated tasks for: /var/www/my_app/current/config/schedule.rb
When I run grep CRON /var/log/syslog:
Jun 29 17:22:01 my_server CRON[21164]: (root) CMD (/bin/bash -l -c 'cd /var/www/my_app/current && RAILS_ENV=staging bundle exec rake cron_test')
Any ideas?
Thanks
What happens when you manually run the command from crontab on the console? Try to run in. See if there are any errors.
/bin/bash -l -c 'cd /var/www/my_app/current && RAILS_ENV=staging bundle exec rake cron_test'
Might be something with local or cron environment. Also logs would be great, capturing any running errors. You can set output log to capture any problems with crontab running the command.
set :output, '/path/to/file.log'
for you example:
set :output, '/var/log/my_app.cron.log'
set :environment, "staging"
set :path, "/var/www/my_app/current"
every 2.minutes do
# specify the task name as a string
rake 'cron_test'
end
Here's the documentation whenever output redirection
Thanks it is working now!
When I created the /var/log/staging_cron.log I read this:
/bin/bash: bundle: command not found
I added env :PATH, ENV['PATH'] on the first line of my schedule.rb, updated the crontab (whenever --update-crontab) and now my test file is well created and updated.
I've read this post Whenever errors and tried to implement the recommendations to no avail. I'm still receiving '/bin/bash: bundle: command not found' error.
On Amazon EC2.
which ruby
/usr/local/bin/ruby
which bundler
/usr/local/bin/bundler
schedule.rb
env :PATH, ENV['PATH']
require File.expand_path('../application', __FILE__)
set :output, "log/cron_log.log"
every 1.minutes do
rake "calculate:calculate"
end
crontab -e
/bin/bash -l -c 'cd /srv/www/myapp/releases/20141022032959 && RAILS_ENV=development bundle exec rake calculate:calculate --silent >> log/cron_log.log 2>&1'
tail -f log/cron_log.log
/bin/bash: bundle: command not found
When I copy the command out of crontab and run it directly, everything works fine (cd /srv/www/myapp/releases/20141022032959 && RAILS_ENV=development bundle exec rake calculate:calculate --silent >> log/cron_log.log 2>&1). It's the prepending of /bin/bash that's messing this up.
How do I get schedule.rb / whenever gem to recognize correct PATH.
Forget about PATH settings in cron files. Setting the PATH does not work.
Set the path to bundle explicitly in your config/schedule.rb
set :bundle_command, "/usr/local/bin/bundle exec"
Edit: exec added so that task can run
If none of the above solution works this did it for me without any additional setup
rvm cron setup
This will include all the right paths for gems so you do this on your machine and you are good to go.
If using rbenv, the path is "/home/YOUR_USER/.rbenv/shims/bundle", so you shoud write at the top of schedule.rb..:
set :bundle_command, "/home/YOUR_USER/.rbenv/shims/bundle exec"
I follow the railscast whenever by javan tutorial but I seems to unable to make it happen.
Is there a MUST to install capistrano to have cron job? it is because I don't have the deploy.rb. I list down the steps in details. If there any steps I had missed to cause my cron not working? I always get a report say I got a new mail but I didnt send any email operation.
Step1:
wheneverize .
====> schedule.rb in config folder
Step 2:
[Scheduler.rb]
every '1 * * * *' do
runner 'Company.count'
end
Step 3: [what is "store"?]
whenever --update-crontab store
Step 4: [config/deploy.rb]<-- I don't have deploy files so I create it myself.
after "deploy:symlink", "deploy:update_crontab"
namespace :deploy do
desc "Update the crontab file"
task :update_crontab, :roles => :db do
run "cd #{release_path} && whenever --update-crontab #{application}"
end
end
Step 5 :
whenever --update-crontab store
crontab -l
What have I missed? why it didnt work? Please enlighten me step by step because I am newbie in ROR.. thanks.
The Whenever docs have an example of deploying Whenever with Capistrano. Just add the following to the top of your Capistrano deploy config.
set :whenever_command, "bundle exec whenever" # set this first if using bundler
require "whenever/capistrano"
Then Whenever will install into cron as part of the deploy.
UPDATE
To test that Whenever was successfully updated cron, ssh to the target machine as the Capistrano deploy user for the target machine and run crontab -l. You should see output similar to this:
crontab -l
# Begin Whenever generated tasks for: app_name
0 0 * * * /bin/bash -l -c 'cd /opt/path/app_name/releases/20120321133343 && RAILS_ENV=production rake group:task --silent'
0 3 * * 6 /bin/bash -l -c '/opt/path/app_name/shared/bin/script'
# End Whenever generated tasks for: app_name
I have an application that contains a bunch of tasks, and every day I want to run a cron job that creates a DayTask for each Task in the database. A Task has_many DayTasks and these daytasks are what users will be checking off every day. I'm using the whenever gem but it doesn't seem to be running at all. Any ideas?
config/schedule.rb
every 1.day, :at => "12:01am" do
runner "Task.generate_tasks_for_day"
end
Task.rb
def generate_tasks_for_day
Task.all.each do |task|
task.day_tasks.create(:target_date => Date.today)
end
end
result of running the 'whenever command'
1 0 * * * /bin/bash -l -c 'cd /home/grant/rails_projects/GoalTwist && script/rails runner -e production '\''Task.generate_tasks_for_day'\'''
Note: I've been changing the times in config/schedule.rb every time I want to test run it.
Finally I have solved how to run the gem Whenever.
It's working good on production, but not in development mode (I think that to working good in dev mode you must do some tricks).
Then, these are the processes to do:
install the gem
write your scheduler.rb file
push to the remote server
login to the remote server (for example with ssh)
see if whenever is good uploaded by running in terminal: whenever
update whenever crontab by running: whenever --update-crontab
restart the server crontab (for example in Ubuntu server): sudo service cron restart
check if crontab is good implemented on the server: crontab -l
That's it!
Personally, I prefer to set up my crons directly from the server:
Edit the crontab: crontab -e
Append my cron (e.g. every day at 5:00 AM - can be little different for not-Linux-based server):
0 5 * * * /bin/bash -l -c 'cd /path_to_my_app/current && RAILS_ENV=production bundle exec rake my_cron_rake'
Check if good implemented: crontab -l
Done
You have to actually register the job with the crontab by running:
whenever --update-crontab
Also if you're trying to get jobs running locally, add
:environment => "development" to your task
runner "MyTask.some_action", :environment => "development"
Try to execute the whenever generated command directly from terminal or add the following line
MAILTO=your#emailadress.com
to your crontab.
if whenever command gives you -bash: whenever: command not found, try bundle exec whenever
This question will probably only make sense if you know about the whenever gem for creating cron jobs. I have a task in my schedule.rb like
every 1.day, :at => '4am' do
command "cd #{RAILS_ROOT} && rake thinking_sphinx:stop RAILS_ENV=#{RAILS_ENV}"
command "cd #{RAILS_ROOT} && rake thinking_sphinx:index RAILS_ENV=#{RAILS_ENV}"
command "cd #{RAILS_ROOT} && rake thinking_sphinx:start RAILS_ENV=#{RAILS_ENV}"
end
However when I update my crontab using
whenever --update-crontab appname --set environment=production
the cron jobs still have RAILS_ENV=development. My tasks on production and development are the same right now, I just need to change the environment variable because thinking_sphinx needs to know the current environment. Any ideas on how to do this?
Thanks!
Whenever doesn't detect your environment, it just defaults to using production.
You can set the environment for all jobs using set:
set :environment, 'staging'
Or per job:
every 2.hours do
runner 'My.runner', :environment => 'staging'
end
Don't write the RAILS_ENV variable. It should set it automatically.
every 1.day, :at => '4am' do
command "cd #{RAILS_ROOT} && rake thinking_sphinx:stop"
command "cd #{RAILS_ROOT} && rake thinking_sphinx:index"
command "cd #{RAILS_ROOT} && rake thinking_sphinx:start"
end
It works in my app:
every 4.days do
runner "AnotherModel.prune_old_records"
end
$ whenever --set environment=production
0 0 1,5,9,13,17,21,25,29 * * /Users/weppos/Sites/git/app/script/runner -e production "AnotherModel.prune_old_records"
$ whenever --set environment=development
0 0 1,5,9,13,17,21,25,29 * * /Users/weppos/Sites/git/app/script/runner -e development "AnotherModel.prune_old_records"
For Whenever (0.9.2)
Use the #environment variable for environment check:
case #environment
when 'production'
every 1.minutes do
rake "user:take_sample"
end
when 'development'
every 1.minutes do
rake "user:dev_sample"
end
end
Something else you may want to try if you're using bundler and capistrano.
In your deploy.rb file, when you set the :whenever_command, DO NOT simply do this:
set :whenever_command, "bundle exec whenever"
Instead, do this:
set(:whenever_command) { "RAILS_ENV=#{rails_env} bundle exec whenever" }
Now, the RAILS_ENV environment variable will be available when the schedule.rb file is loaded, so in schedule.rb you can now do this:
set :environment, ENV['RAILS_ENV']
Voila! You're ready to go.
This questions has been open a long time so I thought I would share what worked with whenever 0.9.7, Ruby 2.4.0, and RAILS 5.0.1. In the previously mentioned answer there are a lot of close tries but syntax error plagues them. Below is what worked and is very simple approach.
schedule.rb
require File.expand_path(File.dirname(__FILE__) + '/environment')
set :output, {:standard => 'log/cron_log.log', :error => 'log/cron_error_log.log'}
env :PATH, ENV['PATH']
every :day, :at => '10am' do
rake "somejob:run", :environment => #environment
end
Update the crontab(dev)
whenever --set 'environment=development' --update-crontab
Results(dev)
0 10 * * * /bin/bash -l -c 'cd /my/rails/app && RAILS_ENV=development bundle exec rake somejob:run --silent >> log/cron_log.log 2>> log/cron_error_log.log'
Update the crontab(prod)
whenever --set 'environment=production' --update-crontab
Results(prod)
0 10 * * * /bin/bash -l -c 'cd /my/rails/app && RAILS_ENV=production bundle exec rake somejob:run --silent >> log/cron_log.log 2>> log/cron_error_log.log'
Hopefully this can help someone out.
Happy Coding this!
Watch out if you want to pass more than one param to whenever.
You have to do it like that:
whenever --update-crontab appname --set 'environment=production&cron_log=/path/to/log'
Latest whenever allows easy Capistrano integration. You can add following to deploy.rb:
set :whenever_environment, defer { stage }
set :whenever_identifier, defer { "#{application}-#{stage}" }
require "whenever/capistrano"
I was having an issue where environment wasn't being set up for whenever cron jobs - /usr/bin/bundle was being picked up instead of /usr/local/bin/bundle.
The solution was to add following to top of schedule.rb
env 'PATH', ENV['PATH']
Add the following line of code at top of config/schedule.rb.
ENV['RAILS_ENV'] = "#{#pre_set_variables[:environment]}"
and update the crontab using following command.
whenever --update-crontab pvcnxt --set 'environment=production'
and then finally restart crontab using command
service crond restart
Thats it!
Final config/schedule.rb looks this way
ENV['RAILS_ENV'] = "#{#pre_set_variables[:environment]}"
env :PATH, ENV['PATH']
require File.expand_path(File.dirname(__FILE__) + "/environment")
set :output, "#{Rails.root}/logs/cron_log_#{ENV['RAILS_ENV']}.log"
every 1.day, :at => '00:00 am' do
command "cd #{Rails.root}/lib/tasks && rake clean__posts_table_rake"
end
I would consider using the "rake" shortcut to make it even cleaner:
every 1.day, :at => '4am' do
rake "thinking_sphinx:stop"
rake "thinking_sphinx:index"
rake "thinking_sphinx:start"
end