38

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!

Tony
  • 18,776
  • 31
  • 129
  • 193
  • In my particular case (starting delayed_job) I got this working using `command "RAILS_ENV=#{@environment} #{Whenever.path}/bin/delayed_job start"` – Besi Jul 06 '18 at 17:59
  • If you run rake you may also use the `rake` command within the `whenever` context. – Besi Jul 06 '18 at 17:59

10 Answers10

97

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 
AJcodez
  • 31,780
  • 20
  • 84
  • 118
Trung LE
  • 971
  • 6
  • 2
26

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"
Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
23

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
marco
  • 98
  • 5
yogendra689
  • 231
  • 2
  • 2
  • 9
    Note, however, that the @environment variable is always 'production' by default. You have to `whenever --set environment=development --write-crontab` when spitting out your jobs and then this answer will work. – Mike A Jul 10 '14 at 18:43
16

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.

Tim Lowrimore
  • 2,024
  • 1
  • 17
  • 9
  • I got this: failed: "sh -c 'cd (REMOVED)/releases/20140127213854 && RAILS_ENV=production bundle exec whenever --update-crontab (REMOVED) --set environment=production --roles db'" on (REMOVED) – Pavan Katepalli Jan 27 '14 at 21:46
14

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!

Jon R.
  • 977
  • 6
  • 12
12

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'
kaczor1984
  • 467
  • 2
  • 12
  • 22
6

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"
Laurynas
  • 3,829
  • 2
  • 32
  • 22
1

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']
Snips
  • 6,575
  • 7
  • 40
  • 64
0

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
Satishakumar Awati
  • 3,604
  • 1
  • 29
  • 50
-10

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
  • 31
    This answer doesn't tell how to change the environment, it's just giving a way to make the task cleaner. Check Trung LE's answer for the real way to do it – DallaRosa Dec 19 '12 at 17:00
  • 1
    Does not answer the question at all. – Benjamin Harel Feb 23 '16 at 17:28
  • Please note that the `rake` command **does** in fact add the `RAILS_ENV` to the command that ends up in the `crontab`. – Besi Jul 06 '18 at 18:00