2014年4月19日(土)に開催された Symfony 勉強会 #6 で 「Vagrant で Symfony 開発」というタイトルで LT してきました。うまく話せなかったので口頭で話したことも含め、伝えたかったことを整理しました。
資料です。
VagrantでSymfony開発
目次
- なぜ Vagrant を使おうと思ったか
- Vagrant の synced_folder を使った開発スタイル
- synced_folder は Symfony だと遅い
- Mac の場合は synced_folder を NFS にする
- Windows の場合は Samba を使う
- キャッシュを RAM ディスクに出力
- Xdebug は使わない
- Windows はトラブル多し
- おまけ:Symfony お試し用 Vagrantfile と Chef レシピ
なぜ Vagrant を使おうと思ったか
私は現在、仕事で複数の LAMP 案件を担当していますが、会社から支給されている PC は Windows です。VirtualBox で案件ごとに複数の仮想 Linux を立ち上げて開発しています。
Windows 側でやっていることは、会社の共有フォルダへのアクセス、仕様書の読み書き、メールのやりとり、SSH で各環境へ接続してデータ見たりログ見たり、などです。Windows 側では開発はしていなくて、開発はすべて仮想 OS 上の Linux で行っています。このスタイルで仕事をしていると、ホスト OS とゲスト OS のウィンドウ切り替えが何度も発生して、結構面倒です。チームからも「しんどいので Windows で開発したい」という声が問題点として上がっていました。
そんな折、Vagrant の synced_folder を使った開発手法を見かけて「これだ!」と思い試してみたわけです。
Vagrant の synced_folder を使った開発スタイル
- Vagrant の synced_folder で、ホスト OS とゲスト OS のフォルダを共有
- 共有フォルダを Web サーバのドキュメントルートにして、Symfony を丸ごと配置
- ソースコード編集や Git 操作はホスト OS から
- ブラウザからの動作確認もホスト OS で
一見とても良さそうに感じましたが、実際のプロジェクトに適用してみると一筋縄ではいきませんでした。
synced_folder は Symfony だと遅い
Symfony プロジェクトを synced_folder に丸ごと放り込むと、パフォーマンスが悪くなります。ブラウザからの 1 リクエスト処理に 5秒 〜 10秒くらいかかるので、とても開発できる状態ではありませんでした。
何とかならないか調べてみた所、海外のサイトにいくつか対策が紹介されていました。
Mac の場合は synced_folder を NFS にする
ホスト OS が Mac の場合は、synced_folder の type を NFS にすると、かなりパフォーマンスが改善されます。
# Vagrantfile
config.vm.synced_folder "host_folder", "guest_folder", type: "nfs"
Mac は以下コマンドで NFS を有効にします。
# MacのNFSを有効化
$ sudo touch /etc/exports
$ sudo nfsd enable
# 仮想OS再起動
$ vagrant reload
Linux がホスト OS の場合は試していませんが、NFS を有効にするだけで多分大丈夫かと思います。
Windows の場合は Samba を使う
ホストOSがWindowsの場合は NFS を利用できないので、仮想 OS に Samba を入れてフォルダを共有します。synced_folder は使わないので無効にしています。
# Vagrantfile
# config.vm.synced_folder "host_folder", "guest_folder", :create => true, :owner=> 'vagrant', :group=>'vagrant', :mount_options => ['dmode=775,fmode=664']
キャッシュを RAM ディスクに出力
AppKernel.php にメソッド追加
Symfony のキャッシュとログを RAM ディスクに出力する方法も効果があります。app/AppKernel.php に以下メソッドを追加すると、env が dev と test の時だけキャッシュを RAM ディスクに出力するようになります。
app/AppKernel.php
public function getCacheDir()
{
if (in_array($this->environment, array('dev', 'test'))) {
return '/dev/shm/symfony/cache/' . $this->environment;
}
return parent::getCacheDir();
}
public function getLogDir()
{
if (in_array($this->environment, array('dev', 'test'))) {
return '/dev/shm/symfony/logs';
}
return parent::getLogDir();
}
PhpStorm の Symfony2-Plugin 向けに、RAM ディスクのキャッシュを共有フォルダにコピー
キャッシュを RAM ディスクに出力すると速くなりますが、別のところで問題が発生します。
PhpStorm の Symfony2-Plugin は入力補完にキャッシュを利用していて、共有フォルダのキャッシュが更新されなくなると補完が効かなくなります。この状況はかなり辛いので、RAM ディスクに出力したキャッシュを rsync で共有フォルダに定期的にコピーして対処します。
以下のシェルスクリプトを cron で 10 分に 1回 実行しています。
#!/bin/sh
if [ -e /dev/shm/symfony/cache/dev/appDevUrlGenerator.php ]; then
rsync -tq /dev/shm/symfony/cache/dev/appDevUrlGenerator.php /var/www/vagrant/symfony/app/cache
rsync -trq /dev/shm/symfony/cache/dev/translations /var/www/vagrant/symfony/app/cache
rsync -tq /dev/shm/symfony/cache/dev/appDevDebugProjectContainer.xml /var/www/vagrant/symfony/app/cache
fi
Xdebug は使わない
Xdebug は遅いので無効にしておきましょう。「デバッガを立ち上げずにテストを書こう」という話が Symfony 勉強会でも出ていました。
Windows はトラブル多し
Samba によるファイル共有は、パフォーマンスは問題ありません。
ですが、共有フォルダ上のファイルのパーミッションと、Git にコミットされているパーミッションで差分が発生してしまったり、なかなか難儀でした。単に Samba や Windows の Git を使いこなせていないだけなのかもしれませんが。
Windows は Samba で頑張るより Vagrant1.5 で追加された rsync による synced_folder の同期を使うのが良さそうです。rsync による同期は、現時点では同期がホスト OS からゲスト OS への一方通行なので Symfony 開発での利用は難しいですが、改善の動きがあるので今後に期待しましょう。
ちなみに Vagrant1.5 で追加された synced_folder type: smb は上手く動きませんでした。管理者権限で vagrant up すると応答が返ってこない状態に・・・。どなたか動かせた方はいらっしゃいませんか。
おまけ:Symfony お試し用 Vagrantfile と Chef レシピ
私が Symfony で何か試したいときに使っている Vagrantfile と Chef レシピを公開します。Symfony を試したい方は使ってみてください。synced_folder の重さも体感できます。このレシピは、今後もどんどん進化させていく予定です。
karakaram/vagrant-php-symfony2-sandbox | GitHub
Windows7 と Mac OSX Mountain Lion で動作確認を取っています。セットアップされる内容は以下の通り。
- CentOS6.5
- Nginx, PHP-FPM
- PHP5.5, OPcache, APCu, Xdebug, PHPUnit, Composer
- MySQL5.6
- Samba
- Symfony2.4
vagrant up 後、以下 URL ですぐに Symfony を試すことができます。
# phpinfo
http://192.168.33.10/symfony/web/_profiler/phpinfo
# Symfony2 デモ画面
http://192.168.33.10/symfony/web/
ホスト OS の共有ディレクトリは、ホームディレクトリの直下に vagrant_symfony2_sync という名前で作られます。適宜修正してください。
おわりに
Windows で Symfony2 開発するときに Vagrant を利用したい、という当初の目的はまだ達成できていませんが、いいところまで来ていると思います。引き続き最新の情報を追いかけたいと思います。
最後になりましたが、会場を提供してくださった株式会社フォトクリエイト様、スタッフの皆様、発表を聞いてくださった皆様に感謝申し上げます。