Capistrano3では、Capistrano2にあった deploy_via :copy
が標準で導入されず、プライベートリポジトリからのソースコードのデプロイがしにくい状況でした。
当時、涙をのんでCapistrano2の継続利用を選択した人も多いと思います。
しかし、今はGitのリポジトリであれば、capistrano-scm-gitcopy.gem を使って簡単に deploy_via :copy
相当のデプロイが可能です。
というわけで、手順を追って環境を作ってみます。
Capistrano3の環境を構築する
適当なディレクトリを作ってGemfileを作成します。
$ bundle init
Gemfileには capistrano
だけでなく、capistrano-scm-gitcopy
も記載します。
source "https://rubygems.org"
gem "capistrano"
gem "capistrano-scm-gitcopy"
Capistrano3をインストールして初期設定をします。
$ bundle install
$ bundle exec cap install
Capistrano2の capistrano-ext-multistage
相当の環境切り替えは既にCapistrano3では標準搭載されているので、それを利用する形で実施します。
ディレクトリ構成
.
├── Capfile
├── Gemfile
├── Gemfile.lock
├── config
│ ├── deploy
│ │ ├── production.rb
│ │ └── staging.rb
│ ├── deploy.rb
│ ├── production
│ │ └── app_local.php
│ └── staging
│ └── app_local.php
├── lib
│ └── capistrano
│ └── tasks
└── log
└── capistrano.log
Capistrano3では、
app_local.php
のようなファイルはリポジトリに含めずデプロイ先のsharedディレクトリ置くことを推奨していますが、今回はローカルファイルをアップロードをする方法を取ります。
deploy.rb
かなり雑ですが、CakePHP3の場合のサンプルはこんな感じでしょうか。
# config valid only for current version of Capistrano
lock '3.6.1'
set :application, 'my_app_name'
set :repo_url, 'git@github.com:k1LoW/my_app_name.git'
# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
set :deploy_to, '/var/www/deploy/to'
set :scm, :gitcopy
set :pty, true
append :linked_dirs, 'tmp/cache/models', 'tmp/cache/persistent', 'tmp/cache/views', 'logs'
set :keep_releases, 5
namespace :deploy do
desc 'Setup CakePHP app'
task :setapp do
on roles(:all) do
within release_path do
# @notice https://github.com/capistrano/capistrano/issues/719
execute :sudo, :chmod, '-R', '777', 'tmp/'
execute :rm, '-rf', 'tmp/cache/models/*'
execute :rm, '-rf', 'tmp/cache/persistent/*'
execute :rm, '-rf', 'tmp/cache/views/*'
execute :curl, '-s', 'http://getcomposer.org/installer', '|', 'php'
execute :php, 'composer.phar', 'install', '--no-dev'
end
upload!("#{File.dirname(__FILE__)}/#{fetch(:stage)}/app_local.php", "#{release_path}/config/app_local.php")
end
end
desc 'Migrate database'
task :migrate do
on roles(:all) do
within release_path do
execute 'bin/cake', 'migrations', 'migrate'
end
end
end
end
after 'deploy:symlink:linked_dirs', 'deploy:setapp'
after 'deploy:setapp', 'deploy:migrate'
ポイントは set :scm, :gitcopy
ですね。これで deploy_via :copy
と同じような動きをします。
あとは
$ bundle exec cap staging deploy
や
$ bundle exec cap production deploy
を実行したら、プライベートリポジトリからソースコードが一旦ローカルにcloneされて、tarでまとめてデプロイが開始されます。
これで、CakePHP3のBakerの皆さんも思う存分Capistrano3が使えますね!
以下、注意点
within *_path do
が withinじゃなくなる問題
スペースが入っている文字列でコマンドを表すと発動します。これはバックエンドのSSHKitの仕様っぽいので、しっかり分割しましょう。
実行時にSkipping taskエラーがでる問題
Skipping task `gitcopy:set_current_revision'.
Capistrano tasks may only be invoked once. Since task `gitcopy:set_current_revision' was previously invoked, invoke("gitcopy:set_current_revision") at /Users/k1low/.anyenv/envs/rbenv/versions/2.3.1/lib/ru
by/gems/2.3.0/gems/capistrano-3.6.1/lib/capistrano/tasks/deploy.rake:228 will be skipped.
If you really meant to run this task again, first call Rake::Task["gitcopy:set_current_revision"].reenable
THIS BEHAVIOR MAY CHANGE IN A FUTURE VERSION OF CAPISTRANO. Please join the conversation here if this affects you.
https://github.com/capistrano/capistrano/issues/1686
これは、Rakeの #invoke
は「1回実行すると、reenable
を明示的に実行しないかぎり、同じタスクが2回目以降実行できなくなる」仕様らしいのですが、それがCapistranoでの利用想定と合っていないことによる問題のようです。
(Capistranoとしては、対応を議論中のようにみえます)。
実際は capistrano-scm-gitcopy.gem でエラーが出ているのですが、今のところ問題は発生していないので大丈夫だと思います。