Laravelでも簡単デプロイしよう

[Laravel Advent Calendar 2013](http://qiita.com/advent-calendar/2013/laravel) の22日目です。

ここまでアップされてきた21個の記事を読んでわかるかと思いますが
Laravelはとても使いやすいフレームワークだと思います。

CakePHPやSymphony、Codeigniter、FuelPHPなど他のPHPフレームワークも
それぞれに特徴を持っていて、良い点も悪い点も様々だと思いますので
コンテキストに応じて使い分ければ良いのではと思います。

が、フレームワークは「やりたいこと」を実現するための手段の１つでしかありません。
開発した仕組みが、どのようになればシアワセなのか？
最終的には（自分も含めて）誰かの役に立つこと、ではないでしょうか？
そして「役に立つこと」がどんなことなのか、どんな機能なのか、は日々変化します。
私たちは、その変化に対応して行かなければなりません。
そのためにはできるだけ早く継続的に、プログラムをリリースしていく必要があります。

しかし毎回、人手によるテストやリリースを行っていたのでは、
そういった対応が難しくなります。

そこで「自動化」です。
自動化と言っても、

- 開発環境の作成
- テスト
- デプロイ

などいろいろと自動化できるポイントがありますが、
今回はサーバへのプログラムデプロイの自動化について記載します。
Laravel4を、Capistranoを使って、ステージングや本番環境にデプロイする例です。

Capistranoインストールからデプロイ実行までの一連の流れを
簡単に記載すると、以下の通りとなります。

1. Capistranoをインストール
2. デプロイ定義ファイルを作成
3. デプロイ先の環境設定ファイルを準備
4. デプロイの手順ファイルを定義
5. デプロイの実行

# Capistranoのインストール

まず、デプロイのコマンドを実行したいサーバに
Capistranoをインストールします。
（Capistranoの利用にはRubyが必須なので、
　先にRubyの導入を行ってから実施してください）

```shell-session
sudo gem install capistrano
```

Capistrano本体と一緒にプラグインも入れておくと
いろいろ便利です。

```shell-session
sudo gem install capistrano_colors
sudo gem install capistrano-ext
sudo gem install railsless-deploy
```

#定義ファイルの作成

続いてデプロイ定義ファイルを作成します。
ファイルを作成したいディレクトリに移動したら、

```shell-session
capify .
```

と実行します。
すると下記のようなメッセージが表示されファイルが作成されます。

```shell-session
[add] making directory ‘./config’
[add] writing ‘./config/deploy.rb’
[add] writing ‘./Capfile’
[done] capified!
```

次に、設定ファイルの中身を編集します。
この記事で示すサンプルは、下記のようなケースです。

- デプロイ先を複数設定する（develop、production）
- ソースコードはBitbucketに入ってる
- デプロイ先はAmazonEC2
- デプロイ時はローカル端末に一旦ファイルをチェックアウトして、まるごとアップロードする

A. デプロイ先環境別の設定ファイル（config/deploy/develop.rb）

```rb:develop.rb
# develop
role :web, *%w[
  dev.sample.com
]
set :user, "deployuser"
ssh_options[:keys] = %w(/Users/sample/keys/ec2-key.pem)
```

上記でWebサーバの接続先と接続ユーザー名（デプロイ専用のユーザー）を指定します。
接続は鍵認証によるSSH接続を行うようにしているため、
キーファイルの場所もここで指定しています。
パスワードによる接続を行う場合はファイル内に記載してもいいですし、
毎回入力を懇請するようにもできます。他の環境設定ファイルも同様の記載方法です。

B. デプロイ手順の定義ファイル（config/deploy.rb）

```rb:deploy.rb
require "capistrano/ext/multistage"
require "capistrano_colors"
require "railsless-deploy"
require "rubygems"
set :application, "laravel_sample"
 
set :scm, :git
set :repository,  "git@bitbucket.org:kurikazu/laravel_sample"
set :branch, "master"
 
set :deploy_to, "/sites/laravel_sample/app"
set :deploy_via, :copy
set :use_sudo, false
 
namespace :deploy do
  task :finalize_update, :except => { :no_release => true } do
    #change permission for laravel storage directories.
    run "chmod -R 777 #{latest_release}/app/storage/"
  end
end
```

Laravelで使う際に必要なのが16〜19行目のところです。
Laravelでは app/storage の下に書き込み権限を与える必要があるため、
デプロイ後の処理として記載しています。

ちなみに finalize_update タスクは、
デフォルトではRuby用の設定を行うようになっています。
そのままだとLaravelの挙動に必要の無いディレクトリ作成などの処理が
行われてしまうため、処理を上書きすることで止めています。

以上が、ひとまず簡易的にLaravelのデプロイを行うための設定です。

#デプロイの実行

では、デプロイを実行してみます。
初回のデプロイでは、

```shell-session
cap develop deploy:setup
```

と実行して、ディレクトリの作成等を行います。
このコマンドを実行すると、デプロイ先のディレクトリに
current、releases、shared の3つのディレクトリが作られます。
なお、上記の２つめの引数の「develop」はステージを表しています。
（ :deploy_to のディレクトリは作成しておいてください）

次にデプロイを実行します。

```shell-session
cap develop deploy
```

実際にデプロイを実行すると、releases ディレクトリの下に、
デプロイ時間でディレクトリが作成され、
そこにデプロイしたファイル群が格納されます。
そして最新ディレクトリは、current からシンボリックリンクが張られます。

そのため、Apacheで設定するDocumentRootは、
上記の current/public ディレクトリに対して設定すれば良いということになります。

#おわりに

デプロイの自動化は、可能であれば開発の始めから、
特に機能の追加などが無くてもできるようにしておいた方が良いです。

快適なLaravelリリース環境を手に入れて、
ドンドン素敵な仕組みを世の中に送り出しましょう！


明日はふたたび @localdisk さんの登場です。