LoginSignup
8
8

More than 5 years have passed since last update.

Capistrano3 の run_locally で rake タスクを実行する

Last updated at Posted at 2015-04-13

capistrano3 を利用してローカル環境で rake タスクを実行したい場合 (rake assets:precompileや rake タスクを実行した結果を利用したい場合等)、 run_locally を使用します。

今回の環境の場合、リモートサーバー、ローカル環境ともに rbenv を利用していますが、リモートサーバーは RBENV_ROOT が/usr/local/rbenv、rubyのバージョンは 2.1.5 を利用しているため、config/deploy.rbには下記のような設定をしています。

config/deploy.rb
set :rbenv_type, :system
set :rbenv_ruby, '2.1.5'

そして、run_locally を実行するタスクのサンプルはこちら。

lib/capistrano/tasks/sample.cap
namespace :sample do
  desc "run_locally sample"
  task "local" do
    run_locally do
      execute :bundle, :exec, :rake, '-T'
    end
  end
end

このままタスクを実行してみます。

$ bundle exec cap development sample:local
(中略)
INFO[58c12b73] Running /usr/local/rbenv/bin/rbenv exec bundle exec rake -T on localhost
DEBUG[58c12b73] Command: ( RBENV_ROOT=/usr/local/rbenv RBENV_VERSION=2.1.5 /usr/local/rbenv/bin/rbenv exec bundle exec rake -T )
cap aborted!
SSHKit::Command::Failed: bundle exit status: 32512
bundle stdout: Nothing written
bundle stderr: sh: /usr/local/rbenv/bin/rbenv: No such file or directory
(中略)

ローカル環境の RBENV_ROOT は~/.rbenv でしたが、リモートサーバー用の環境変数が引き継がれているため、エラーが発生してしまいました。
ここでは、 run_locally でとくに rbenv の環境変数を気にせずに実行できるよう一旦下記のように修正してみます。

lib/capistrano/tasks/sample.cap
namespace :sample do
  desc "run_locally sample"
  task "local" do
    run_locally do
      execute "bundle exec rake -T"
    end
  end
end
$ bundle exec cap development sample:local
cap aborted!
SSHKit::Command::Failed: bundle exec rake -T exit status: 256
bundle exec rake -T stdout: Nothing written
bundle exec rake -T stderr: rake aborted!
LoadError: cannot load such file -- rails/all
(以下略)

こちらの記事 (http://qiita.com/paty-fakename/items/d198f441434adafaf631) を参考にさせていただいたところ、bundle exec の中で bundle exec を呼び出している状態となっているため、run_locally 内にまで環境変数を引き継いだ状態になってしまっているようです。
そこで、Bundler.with_clean_envを利用してみます。

lib/capistrano/tasks/sample.cap
namespace :sample do
  desc "run_locally sample"
  task "local" do
    run_locally do
      Bundler.with_clean_env do 
        execute "bundle exec rake -T"
      end
    end
  end
end

期待通りの動作になりました。

ただ、rakeタスクが別ディレクトリにある場合は、Dir.chdir('/path/to/your/.../') doで囲ったり、:rails_env を引き継いで実行しようとするとwith rails_env: fetch(:rails_env) doで囲ったりすることになりそうですが、なかなか深いブロックネストになりそう...うーん。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8