whenever icon indicating copy to clipboard operation
whenever copied to clipboard

cron jobs are overwritten for other environments on each deploy

Open JamesChevalier opened this issue 9 years ago • 6 comments

I've been using whenever for years, mostly under capistrano 2, without a hitch. It's been a really great experience - thank you!

I'm deploying a Rails app with capistrano 3 right now, and I'm really confused about how to get multiple environments on a single server to play well with each other. I have two environments, staging and production, on one server, and they keep clobbering each other.

  • If I deploy staging, then all of the cronjobs are removed and replaced with jobs referencing the staging release path and environment. All of the production jobs are gone.
  • If I deploy production, then all of the cronjobs are removed and replaced with jobs referencing the production release path and environment. All of the staging jobs are gone.
  • If I do a case statement in schedule.rb on @environment, and only have jobs set for a when 'production' situation, then when staging is deployed it completely clears the cronjobs. All of the jobs are gone.

I need to get to either of these two situations:

  • Have two sets of jobs (one for staging and one for production) that each persist through either environment's deploy (so, in my example at the bottom, there would be two jobs listed - one for the staging release and one for the production release)
  • One set of jobs (just for production) that persists through either environment's deploy (so, the staging deploy should not remove it)

Can you explain how this is done? I've included my current configuration, below, in case it's helpful.

Capfile

require 'whenever/capistrano'

config/deploy/production.rb

server '1.2.3.4', user: 'username', roles: %w{web app}
set :branch, 'master'
set :deploy_to, '/home/username/production'
set :rails_env, 'production'
set :stage, :production
set :whenever_environment, -> { fetch(:stage) }
set :whenever_identifier, -> { "#{fetch(:application)}_#{fetch(:stage)}" }

config/deploy/staging.rb

server '1.2.3.4', user: 'username', roles: %w{web app}
set :branch, 'staging'
set :deploy_to, '/home/username/staging'
set :rails_env, 'staging'
set :stage, :staging
set :whenever_environment, -> { fetch(:stage) }
set :whenever_identifier, -> { "#{fetch(:application)}_#{fetch(:stage)}" }

config/schedule.rb

set :output, '/log/cron.log'
every 10.minutes do
  runner 'ModelName.method_name'
end

the resulting cronjob after a staging deploy

0,10,20,30,40,50 * * * * /bin/bash -l -c 'cd /home/username/staging/releases/20150317012814 && script/rails runner -e staging '\''ModelName.method_name'\'' >> /log/cron.log 2>&1'

JamesChevalier avatar Mar 17 '15 01:03 JamesChevalier

When you run crontab -l on your server, what do the Whenever comments surrounding the job look like?

javan avatar Mar 18 '15 00:03 javan

Sorry about truncating that.

Relevant line in config/deploy/deploy.rb

set :application, 'application_name'

The resulting cronjob after a staging deploy

# Begin Whenever generated tasks for: application_name
0,10,20,30,40,50 * * * * /bin/bash -l -c 'cd /home/username/staging/releases/20150317012814 && script/rails runner -e staging '\''ModelName.method_name'\'' >> /log/cron.log 2>&1'

# End Whenever generated tasks for: application_name

It seems like whenever isn't applying the whenever_identifier. If it was, and wasn't getting the stage value, I'd expect to see something like this:

# Begin Whenever generated tasks for: application_name_`

JamesChevalier avatar Mar 18 '15 12:03 JamesChevalier

Sounds like Whenever's defaults might be clobbering your settings. Check to see if you're on a version of Capistrano that includes this commit https://github.com/capistrano/capistrano/commit/f040f12353c3ad8f682631463743691b785b3353.

javan avatar Mar 18 '15 14:03 javan

OK, I was at:

  • capistrano: 3.3.5
  • whenever: 0.9.4
  • ruby: 2.1.5
  • rails: 3.2.21

I've upgraded capistrano to 3.4.0, but the issue persists. It seems like that should have fixed it, based on the description/code in that commit.

I'm wondering if I'm using the set lines in the wrong place (they're currently in the staging.rb and production.rb deploy files). I'm also wondering if my syntax is right ... I'm pretty confused about the defer syntax. It seemed like that was a 'capistrano 2' thing, and that -> is now used for capistrano 3.

I notice that the output during the cap deploy is:

INFO [d968b5ba] Running /usr/bin/env cd /home/user_name/production/releases/20150319184240 && bundle exec whenever --set environment=production --update-crontab application_name as [email protected]

It seems like it's not getting the whenever_identifier right there - using application_name instead of application_name_production.

JamesChevalier avatar Mar 18 '15 17:03 JamesChevalier

Hi, I'm having the same problem with the same scenario described by @JamesChevalier. We have three environments (staging, preproduction, and production) at the same server and every time that we deploy at one of them, the crontab file is overwritten, leaving only the jobs for the last deployed environment. It seems that the whenever_identifier is not taken into account 😞

Any news about this? Thanks.

vlledo avatar Aug 24 '18 15:08 vlledo

+1 on this. I'm deploying two applications each with their own crontab but they overwrite each other. I think I'll create a separate user to deploy to as a work around.

danhixon avatar Feb 03 '21 21:02 danhixon