自分への備忘録を兼ねて。
はじめに
Capistranoでアプリケーションをデプロイする場合、リリースディレクトリ(releasesの下のディレクトリ名)はUTCの年月日時分秒が設定されます。
ディレクトリに設定される時刻をUTCからJSTに設定する方法について、Capistrano2での設定方法は簡単に見つかったのですが、Capistrano3での設定方法が見つからなかったので、Capistrano3のソースコードを実際に読んでみました。
なお、確認したCapistranoのバージョンは3.1.0です。
Capistrano2の場合
Capistrano2では
set(:release_name) {
set :deploy_timestamped, true; Time.now.strftime("%Y%m%d%H%M%S")
}
とdeploy.rbに記述することで、リリースディレクトリがJSTの時刻に設定されます。
Capistrano3の場合
Capistrano3でリリースディレクトリの名前をセットしているのは、/path/to/capistrano-3.x.x/lib/capistrano/tasks/deploy.rake の以下のタスクです。
task :new_release_path do
set_release_path
end
ここでは、/path/to/capistrano-3.x.x/lib/capistrano/dsl/paths.rb に定義されている
def set_release_path(timestamp=now)
set(:release_path, releases_path.join(timestamp))
end
を呼び出して、リリースディレクトリの名前をセットしています。
set_release_pathは引数で受け取った変数 timestamp をそのまま別の変数にセットしているので、set_release_pathに変数を渡すようにすればリリースディレクトリを変更することが可能です。
そこで、deploy.rbで以下のようにして、定義されているタスクを一度クリアした上で、set_release_pathに引数を渡す形に書き換えます。
Rake::Task["deploy:new_release_path"].clear
namespace :deploy do
task :new_release_path do
set_release_path(Time.now.strftime("%Y%m%d%H%M%S"))
end
end
これで、JST(正確には、実行環境のタイムゾーンに合わせた時刻)をリリースディレクトリの名前に利用することができます。
なお、私が動作確認しているのは3.1.0ですが、3.4.0のソースコードを見たところ、paths.rbのset_release_pathの処理が多少変わってはいるものの、同じ方法で変更ができそうです。
もしかしたら、Capistrano3であれば、すべて同じ方法でできるかも知れません。
機会があれば試してみたいところですね。
応用編
上述の方法で、UTC以外の時刻をリリースディレクトリの名前に設定することができるようになりましたが、実際のところリリースディレクトリには時刻以外の文字列を利用することも可能です。
そこで、下記のようにすれば、任意の文字列をcapコマンド実行時に渡すことで、日時以外をリリースディレクトリに利用できるようになります。
set :release_date, ENV['RELEASE_DATE'] || Time.now.strftime("%Y%m%d%H%M%S")
Rake::Task["deploy:new_release_path"].clear
namespace :deploy do
task :new_release_path do
set_release_path(fetch(:release_date))
end
end
こうすると、capコマンド実行時に指定がなければ現在時刻が、指定がある場合はそちらの文字列がリリースディレクトリの名前に利用されます。
時刻以外を利用する場合はソート順などを意識する必要がありますが(でないと、ロールバックなどでの挙動がおかしなことになる)、外部から時刻を指定できるようになるとタスクを何段階かに分割して実行するなど、ちょっと変わった実行も可能になります。
興味のある方は、こちらも合わせて試してみてください。