Search code examples
rubycapistranocapistrano3wheneverrvm-capistrano

Why does Capistrano run a command differently


I have been noticing some weird stuff with Capistrano lately. But before I can explain that let me provide some head on from where it is exactly coming from.

As a part of updating my crontab on every deployment. I decided to use whenever/capistrano recipe.

But for some reason(not known to me but I see a issue in github describing the same). Every time I attempt to do so I see following error.

"database configuration does not specify adapter"

Important bit. here how the command look like

INFO [a558a04a] Running ~/.rvm/bin/rvm 2.2.2@thrasher do bundle exec whenever --update-crontab thrasher --set environment=production --roles=app,web,db as [email protected]
DEBUG [a558a04a] Command: cd /home/deploy/project-scp/thrasher/releases/20160129130817 && ~/.rvm/bin/rvm 2.2.2@thrasher do bundle exec whenever --update-crontab thrasher --set environment=production --roles=app,web,db
DEBUG [a558a04a]    scheduling frequent upload job
scheduling daily upload job
DEBUG [a558a04a]    [write] crontab file updated
INFO [a558a04a] Finished in 2.411 seconds with exit status 0 (successful).

Kindly, take a note of the command.

~/.rvm/bin/rvm 2.2.2@thrasher do bundle exec whenever ...

Now, in order to solve this problem. I set the whenever_command, a capistrano variable to look like this.

set :whenever_command,["RAILS_ENV=#{fetch(:stage)",:bundle,:exec,:whenever]

And ...

When I ran the capistrano again, I saw this.

Running /usr/bin/env RAILS=production bundle exec whenever --update-crontab thrasher --set environment=production --roles=app,web,db as [email protected]
DEBUG [b67e3351] Command: cd /home/deploy/project-scp/thrasher/releases/20160129131301 && /usr/bin/env RAILS=production bundle exec whenever --update-crontab thrasher --set environment=production --roles=app,web,db

Command Executed was

/usr/bin/env RAILS=production bundle exec whenever ...

Question:

Why did the 2 time the command did not look like this.

~/.rvm/bin/rvm 2.2.2@thrasher do RAILS_ENV=production bundle exec whenever

Note:

Rails 4.0.4

Capistrano Version: 3.4.0 (Rake Version: 10.5.0)

Ruby ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]

Also using

capistrano/rvm

Update:

In accordance with @will_in_wi answer. To solve the whenever issue I also tried doing this.(inside deploy.rb file.)

namespace :deploy do
   ...
   ...
   before "whenever:update_crontab", "deploy:set_rails_env"

end

Solution

  • Short answer: Placing an environment variable inside the :whenever_command is not the right way to do it. Based on the whenever/capistrano code, you should use :whenever_command_environment_variables.

    Remove your :whenever_command and try this instead:

    set :whenever_command_environment_variables, -> { { :rails_env => fetch(:stage) } }
    

    Long answer: you are using capistrano/rvm, which does some magic with Capistrano's "command map" to automatically prefix certain commands with ~/.rvm/bin/rvm.... One of those certain commands is bundle, for example. If you change the whenever command to no longer start with :bundle, the mapping will no longer work.