おじゃまぷよ系エンジニアメモ

アプリエンジニアからサーバーとインフラエンジニアに転身しました

capistranoでcomposer installしてからrsync

capistranophpのプロジェクトをdeployしようとして
通常のdeploy方式だとdeploy先のサーバーでgit pullしてからcomposer installになってしまうがそうではなくて
deployサーバーでgit pullしてcomposer installしてそれをdeploy先のサーバーにrsyncでファイルを送りたかった
ググったらすぐに見つかるかなぁと思っていたが思いの外ピンポイントな情報がなかったのでメモ

github.com

capistrano-bundle_rsyncを使います GemFileの内容としてはだいたいこんな感じ

source "https://rubygems.org"

gem 'capistrano', '3.8.1'
gem 'capistrano-rbenv'
gem 'capistrano-bundle_rsync'

bundle install –path vendor_bundle でbundle installしましょう。pathを指定しないとデフォルトでvendorになるので、phpのcomposerのvendorと被って余計なものがデプロイされてしまいます。なのでbundleではインストールパスを指定して後でそのパスはrsyncから外すようにします。 後はcapistrano-bundle_rsyncのREADMEに従ってCapfileやconfigファイルを設定します

コピペですがCapfileは

# Load DSL and Setup Up Stages
require 'capistrano/setup'

# Includes default deployment tasks
require 'capistrano/deploy'

# capistrano-3.3.3 - 3.6.1
require 'capistrano/bundle_rsync'

# capistrano-3.7+
require 'capistrano/bundle_rsync/plugin'
install_plugin Capistrano::BundleRsync::Plugin

# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

config/deployにvagrantにdeployする想定のlocal.rbを作ります

server "vagrant"
set :stage, :local
role :web, "vagrant"

問題のdeploy.rbです

# config valid only for current version of Capistrano
lock "3.8.1"

set :branch, ENV['BRANCH'] || 'master'
set :keep_releases, 2
set :scm, :bundle_rsync
set :application, "sample"
set :repo_url, "gitrepo"
set :rsync_options, '-az --delete --delete-excluded --exclude=vendor_bundle'
set :deploy_to, "/var/www/html/example"

# rsync前にcomposer installする
task :pre_rsync_action do
  config = Capistrano::BundleRsync::Config
  run_locally do
       execute ("cd #{config.local_release_path} && php composer.phar install --no-dev")
  end
end

before "bundle_rsync:rsync_release", "pre_rsync_action"

rsync_optionでbundle installしたディレクトリはrsyncから外しています。 capistrano-bundle_rsyncはいろいろなタイミングでフックポイントがあるのでrsyncが実行される前にcomposer installを実行するようにしています。
rsyncされるディレクトリーはcapistranoがカレントディレクトリの下に「.local_repo」というディレクトリを作り、さらにその下にできる「releases/{datetime}」ディレクトリがrsyncされるディレクトリです。 そのrsyncされるパスを取得するのがdeploy.rbの「config.local_release_path」の部分です
ここまでできたら後はgitにGemfile.lockをPushして「bundle exec cap local deploy」を実行するだけです。
今回はcomposer installしただけですが、その他にも設定ファイルなどをこのタイミングでそのstageに合わせてコピーするなど色々できます。
ごちゃごちゃ書きましたが結果としてはcapistrano-bundle_rsyncのREADME通りに書いてdeploy.rbだけ少し改良するだけで良いという話です