モーグルとカバとパウダーの日記

モーグルやカバ(EXカービング)山スキー(BC)などがメインの日記でした。今は仕事のコンピュータ系のネタが主になっています。以前はスパム対策関連が多かったのですが最近はディープラーニング関連が多めです。

Vagrantの共有フォルダをapacheの公開ディレクトリにしていると更新が反映されない問題

今、WindowsCakePHPの開発を行っているのですが、Vagrant上にCentOSを入れ、共有フォルダ /vagrant 以下にディレクトリを作ってそこにCakePHPを入れ、apacheの設定でそこをDocumentRootにして使っています。
開発はWindows上のNetBeansで直接共有フォルダのソースを編集するようにしています。
これだとWindows上のXAMPP使ってるのと同じような感じに開発が進められます。


さてその環境で、Javascriptのファイルを編集しても編集が反映されない、一度ファイル名を変更して、再度ファイル名を戻すとちゃんと動くんだけど… というような相談を受けました。
最初、CakePHPのキャッシュやブラウザキャッシュを疑ったのですが、Cake関係ないファイルでテストしても同様の状況が再現できて違うことがわかりました。
しかも色々とテストしてみると、単に修正が反映されない時ばかりではなく、なんか過去に修正した時の内容が出てきたり、一部欠けたものが出てくることがあったりと、不安定な動作をすることがあることがわかりました。


そこで今度はApache自身のキャッシュを疑ったのですが、Apacheにそんな機構あったっけ?と思ったのと、あと他ではこういうの経験したことが無かったから、Vagrantの共有フォルダがらみなんだろうなあ、と考えました。
そこで「vagrant 共有フォルダ apache」でぐぐったところすぐに答えがわかりました。


Vagrantの共有フォルダをDocumentRootに設定した場合にファイルの変更が反映されない | trapon : experience
Virtualbox上のApacheでホストマシンと共有している静的ファイル(CSSなど)の更新が検知されない問題を解決する方法 | tipshare.info


VirtualboxVagrantではそこそこメジャーなトラブルっぽいです。
結局、共有フォルダはNFSとかと同じような機構なので、EnableMMAPとEnableSendfileが効いているとうまく動かないことが起こるそうです。


/etc/httpd/conf/httpd.confのデフォルト設定ファイルにもこの2項目の記述がありコメントになっているため、そこを外してやるか、無ければ下記のようにoffの記述を追加してやります。

EnableMMAP off
EnableSendfile off


これだけで無事に解決できました。


ただ自分の例のように、途中にキャッシュサーバやフレームワークを利用している場合、どこのキャッシュのせいでこの問題が起こっているのか、がわかるまでに結構時間がかかるのではないかと思います。


(追記)

さとうふみやすさんより下記のように情報をいただきました。


VirtualBox の shared folder で sendfile(2) がバグってるやつを調べた - hibomaのはてなダイアリー

Nginx や Apache で sendfile(2) サポートを有効にしていると VirtualBox の shared folder ( /vagrant ) のファイルを ホストOS側からで更新しても反映されないバグが知られています。

・generic_file_splice_read はファイルが書き換えられているかどうかを確認しない
・ホストOSでファイルが更新されていても generic_file_splice_read は知らず知らず 古いページキャッシュを返してしまう
という問題

VirtualBoxのvboxsfに問題があるようで、根本解決できる道はありそうなんですが、未だにパッチされてないからなかなか難しそうなのか。