前回の記事「FuelPHPアプリをCapistrano3でデプロイ – Chef環境構築編」で準備した環境に、Capistrano3でFuelPHPをデプロイする手順をまとめる

FuelPHPは、Coreをsubmoduleのままにしている場合は、git submoduleに対応させる必要がある
ComposerによるPHPパッケージの追加はCapistrano::Composerプラグインを利用する

公式のREADMEに従ってプロジェクトを作した後に、FuelPHP固有の設定を追加していく

ssh-keyをbitbucketに登録

PCからの直接デプロイする場合は、すでにリポジトリにローカルの公開キーを登録済みと思われるが、登録していない場合は、
ssh-keyを生成してbitbucketに登録」あたりを参考に、公開キーをBitbucketに登録しておく

Capistranoのインストール

まずは、プロジェクト用ディレクトリを作成

$ mkdir fuelphp-cap

Gemfileを作成

source 'https://rubygems.org'

gem 'capistrano', '~> 3.4.0'

bundle installを実行
PCからの実行を考えるとローカルインストールしておきたいので--pathをつけている

$ bundle install --path vendor/bundle

Capistranoプロジェクトを作る

cap installコマンドでプロジェクトが生成される

$ bundle exec cap install

以下のような構成のプロジェクトが生成される

$ tree
.
├── Capfile
├── Gemfile
├── Gemfile.lock
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
    └── capistrano
        └── tasks

5 directories, 6 files

Capfileは、Capistranoの実行に必要なモジュールの読み込みを定義する
configディレクトリは、デプロイの実装を含むめる
libは、Capistranoタスクを含める

Chefリポジトリとかぶるディレクトリ・ファイルがないので、小さなプロジェクトの場合は1つのgitリポジトリにまとめてしまっても支障はなさそう
ライフサイクルがChefとCapistoranoでは異なりそうなので分けたほうが良さそうではあるが

基本の設定

リポジトリとデプロイするディレクトリなど、共通の設定はdeploy.rbに記述する
以下は、BitcuketのURLと、デプロイ先としてChefで作成したディレクトリを指定している

# config valid only for current version of Capistrano
lock '3.4.0'

set :application, 'fuelblog'
set :repo_url, 'git@bitbucket.org:hendoh/fuelblog.git'

# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp

# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, '/var/www/fuelblog'

# Default value for linked_dirs is []
set :linked_dirs, fetch(:linked_dirs, []).push('fuel/app/logs', 'fuel/app/tmp')
...

fuel/appのlogsとtmpは、sharedディレクトリに配置するようにlinked_dirsを設定

環境別の定義

role :app, 'fuelphp_web'

server 'fuelphp_web', user: 'deploy'

set :ssh_options, {
  forward_agent: true
}

serverは、~/.ssh/configを定義しssh fuelphp_webでアクセスできるようにしてあれば不要
また、ssh_options.forward_agentを有効にしておくと、リポジトリの秘密キーを対象サーバーに置かなくてもgit clone可能になる
参考: capistrano3でssh agent forwarding

git submodule

FuelPHPのCoreモジュールは、submoduleとしてプロジェクトに含めるが、Capistrano3では、submoduleがサポートされていない

以下のタスクを追加するとsubmoduleも展開してくれるようになる

namespace :git do
  desc 'Copy repo to releases'
  task create_release: :'git:update' do
    on roles(:all) do
      with fetch(:git_environmental_variables) do
        within repo_path do
          execute :git, :clone, '-b', fetch(:branch), '--recursive', '.', release_path
        end
      end
    end
  end
end

Composer

PHPフレームワークもCapistranoを利用する例が多くなていることもあるのか、Composerプラグインが用意されている
Capistrano::Composer

Gemfileにcapistrano-composerを追加

source 'https://rubygems.org'

gem 'capistrano', '~> 3.4.0'
gem 'capistrano-composer'

インストール

$ bundle install

Capfileにモジュールのrequireを追加

# Load DSL and set up stages
require 'capistrano/setup'

# Include default deployment tasks
require 'capistrano/deploy'

require 'capistrano/composer'
...

マイグレーション

デプロイ時にFuelPHPのマイグレーションを実行する
以下のように、deploy.rbにマイグレーションタスクを定義して、デプロイ後に実行するように指定する

namespace :deploy do
  desc "Migrate the database"
  task :migrate do
    on roles(:app) do
      execute "FUEL_ENV=#{fetch(:default_env)[:FUEL_ENV]} php #{release_path}/oil refine migrate"
    end
  end
end

after "deploy", "deploy:migrate"

マイグレーションの実行時に指定する環境変数FUEL_ENVの値#{fetch(:default_env)[:FUEL_ENV]}は、環境ごとの設定ファイルで以下のように指定する

set :default_env, {
    'FUEL_ENV' => 'production'
}

set :linked_files, fetch(:linked_files, []).push('fuel/app/config/production/migrations.php')

また、FuelPHPはマイグレーションのステータスをmigrations.phpファイルに保存するためsharedに配置するようにlinked_filesにセット

デプロイの実行

デプロイの実行時は、Agent forwordingして対象サーバーからリポジトリーBitbucketへのsshアクセスのために秘密キーをssh-addしておく

$ ssh-add ~/.ssh/id_rsa

Composerの実行時はcomposer:installオプションをつけて実行するとデプロイが始まる

$ bundle exec cap staging deploy composer:install