PHP 製デプロイツール「Rocketeer」を使ってみた
こんにちは。西山です。
毎日続く炎天と夕方に来襲する豪雨で夏らしさが一気に全開になりましたね。
今回はデプロイツール「Rocketeer」についてご紹介したいと思います。
これは GitHub上で公開されているオープンソースソフトウェア (OSS) です。リポジトリは
https://github.com/Anahkiasen/rocketeer
にあります。ライセンスは MIT です。
デプロイツールというと、以前の現場で Capistrano を使っていたのですが、これは Ruby 製ですね。
Rocketeer は Capistrano に似た構成を持つ PHP 製のソフトウェアです。普段、PHP の案件に関わることが多いのですが、デプロイツールも同じ PHP で書かれていたほうが安心感(?)がありますよね。
また、Composer や PHPUnit の実行にもデフォルトで対応していて、PHP のプロジェクトに特化した機能が用意されているのもうれしいポイントです。
特に PHP フレームワーク Laravel を使ったプロジェクトでは、Laravel のコマンドラインインタフェースに Rocketeer の操作を統合することができ、相性抜群のようです。
Rocketeer 自体も Laravel のコンポーネント群を使って作られています。
と言いましたが、今回は Laravel ではなく社内で使うことの多い CakePHP のプロジェクトをデプロイする方法を調べてみました。
ソースのデプロイ、Composer の実行、cake シェルからの PHPUnit の実行の手順をまとめてみたいと思います。
「Rocketeer」を使ってみた
環境設定
今回はデプロイコマンドを発行するサーバーとデプロイされるサーバーを一つづつ、ともに Vagrant で用意しました。ローカルのマシンの OSX から、サーバー構成管理ツール Ansible の Vagrant プラグインを使って作成しました。
サーバー構成
サーバーの構成図を下に示します。
node1 がデプロイコマンドを発行するサーバー、node2 がデプロイされるサーバーです。
システム要件
デプロイに Rocketeer を使うには以下の条件を満たしている必要があります。
- PHP と、拡張モジュール php-mcrypt がインストールされていること。
- Git または Subversion がインストールされていること。
- デプロイするソースコードを Git または Subversion で管理していること。
これらに加えて、今回はもちろん Composer と PHPUnit も必要になります。
Rocketeer の準備
インストール
Rocketeer をインストールするには Composer を使うのがよいです。ここでは node1 の /home/vagrant/rocketeer をプロジェクトのルートとします。CakePHP, PHPUnit と合わせて、プロジェクトの composer.json に設定を書きましょう:
1 2 3 4 5 6 7 |
{ "require": { "anahkiasen/rocketeer": "dev-master", "cakephp/cakephp": "2.4.*", "phpunit/phpunit": "3.7.*" } } |
composer install でプロジェクトのルートに vendor ディレクトリが作られ、その中に関連モジュールとともに Rocketeer, CakePHP, PHPUnit がインストールされます。CakePHP のアプリケーション自体もこの、プロジェクトルートに配置しましょう。ファイルの構成は以下のようになります。
初期設定
Rocketeer の実行ファイルは vendor/bin/rocketeer です。コマンド vendor/bin/rocketeer ignite で .rocketeer というディレクトリの中に設定ファイルが生成されます。対話的にいろいろ聞かれますが、とりあえず全てデフォルト値にしておきましょう。
設定ファイルの編集
生成された設定ファイルの変更 が必要な箇所を編集します。今回編集したファイルは以下の3つです。
- config.php :デプロイ先サーバーの接続情報の設定
- remote.php :デプロイ先ディレクトリやデプロイ間で共有するディレクトリ(ログやキャッシュのディレクトリ)の設定
- scm.php :Git リポジトリの設定
具体的な編集内容は下のコミットログを見てください。
ここまでで、Rocketeer の基本的な設定は完了です。
Unit test タスクの作成
次に unit test を行うためのタスクを作成します。Laravel を含む、大抵の PHP プロジェクトではプロジェクトルートに PHPUnit 用の設定ファイル phpunit.xml が存在して、そこで phpunit を実行すればテストが走るようになっています。この形であれば、特に何も設定せずとも Rocketeer でのデプロイ時にテストを実行することができます。
しかし、CakePHP はコマンドラインインタフェースである、cake コマンドから間接的に phpunit を呼び出す形になっていて、Rocketeer のデフォルトでは対応することができません。そこで今回はこの cake コマンドを呼び出す、カスタムタスクを書いてテストを実行することにします。
カスタムタスクは .rocketeer ディレクトリ内に tasks.php という名前のファイルを配置して、それに書きます。Rocketeer デフォルトのテスト実行コードをを参考にすると、以下の様なタスクを作るのがよさそうです。
1 2 3 4 5 6 7 |
<?php use Rocketeer\Facades\Rocketeer; Rocketeer::addTaskListeners('deploy', 'before-symlink', function ($task) { $output = $task->runForCurrentRelease("app/Console/cake test app Model/AppModel"); return $task->checkStatus('Test failed', $output, 'Tests passed successfully.'); }); |
これは、ソースコードの配置が終わり、シンボリックリンクを切り替える前 (before-symlink) にコマンド
app/Console/cake test app Model/AppModel
を実行するタスクです。テストが成功したかどうかを checkStatus() メソッドで判定します。失敗したらテスト結果を出力し、処理を中断するようにします。
実行してみる
では、いよいよデプロイを実行してみましょう。実行コマンドは
vender/bin/rocketeer deploy
です。実行すると、デプロイ先サーバーにディレクトリが作られ、ソースの取得、Composer の実行、PHPUnit の実行が行われます。
デプロイ先サーバーにログインして確認してみると、以下のように過去数回分のデプロイが保存されていて、current という名前のシンボリックリンクが最新のデプロイを指すようになっています。これは Capistrano でもこんな感じでしたね。
ここで実は問題が・・・
さて、これまで実験をしてきたのですが、ここで一つ問題が起こりました。先ほど、ユニットテストに失敗したらデプロイを中断させる、と書きました。その状況を実験してみようと、必ず失敗するテストを書いてデプロイを実施してみたのですが、なんと中断されずに最後まで実行されてしまいます。
こうなってしまう原因がわからず、かなりハマってしまったのですが、Rocketeer のソースコードをデバッガで追跡したり、いろいろやった結果、どうやら上で述べた checkStatus() メソッドがどんな場合も成功扱いの値を返してしまうという不具合があるようです。これは Rocketeer が依存している Laravel のコンポーネントに行われた変更に起因するようでした。なので、このコンポーネント(illuminate/remote) を変更以前のバージョンを使うようにすればとりあえず回避できます。それには、composer.json に illuminate/remote の古いバージョンを指定して、composer update をすればよいです。
この問題について、Rocketeer の作者に質問をしてみました。
https://github.com/Anahkiasen/rocketeer/issues/254
できるだけ急いで修正する、との返信をいただきました。Rocketeer のコア部分の修正が必要そうなので、修正のプルリクエストを送るよりは作者の方に直してもらった方がいいかなと思います。
さて、illuminate/remote を入れ替えた結果、テストが失敗したらちゃんとデプロイが中断されるようになりました。
まとめ
今回は PHP 製デプロイツール Rocekteer についてご紹介しました。Rocketeer は Capistrano 風の操作感をもつ、PHP プロジェクトに特化したデプロイツールです。Composer や PHPUnit の自動実行が簡単にできるのが特徴でしたね。
個人的には、Rocketeer の作者に問い合わせをしたのが初めての OSS 活動(?)という感じがしてドキドキでした。
この記事で使用したサーバー構成の Ansible の設定と、実際にデプロイに使った CakePHP + Rocketeer のプロジェクトは GitHub にて公開しています。興味を持たれた方はいじってみてください。
・Ansible:https://github.com/maple-nishiyama/rocketeer_practice_ansible
・CakePHP + Rocketeer:https://github.com/maple-nishiyama/rocketeer_practice_servers
この記事を書いた人他のメンバーを見る
- Twitter:@d_nishiyama85
- メイプルの技術担当。
くまモン県出身。
たまにくまモンと間違えられることもあるという。
最近書いた記事西山が書いた記事一覧
2014.08.01CakePHPPHP 製デプロイツール「Rocketeer」を使ってみた
2014.07.04ステマ友人が透明人間になりたがっていると聞いて・・・
2014.05.02JavaScriptNode.js でイベントループモデルとノンブロッキングIOを試す
2014.04.14CakePHP開発効率UP!Eclipse + Xdebug で PHP のステップ実行をしよう