Windows + Vagrant + VirtualBoxでLaravelを動かすと、ローディングにかなりの時間がかかって仕事が進まなかったという問題の対処方法を紹介します。NFSを使用する方法です。
Virtual Box の共有フォルダ機能は遅い
ホスト側とゲスト側でプログラムファイルなどを共有するためにVirtualBoxには共有フォルダ機能が存在しますが、デフォルトの共有方法を用いるとかなり遅くなります。
仕事でLaravelを使ったWebサイトをVirtualBoxで構築していたところ、Windows環境やMac環境でも1ページ読み込むのに5秒ほどかかり、まともに仕事ができない状態になってしまいました。
デフォルトのファイル共有機能は、比較的安定性は高く、多くのOSで使用できるのですが、メモリキャッシュなどの機能を使用していないため、ディスクアクセスは遅い欠点があります。
一方、Laravelは大量の依存ファイルを読み込むのでディスクアクセスが大量に発生します。そのため表示が遅くなります。
対処方法
Dockerなどの仮想化技術が使用できるツールに切り替えができるのであれば、切り替えるのをおすすめします(ちなみにDocker ToolBoxはVirtualBoxを使用するので意味ありません...)。それができない場合は、NFSでマウントする機能を使用します。
仕組みは公式ドキュメントをご確認ください。
Windows の場合はプラグインが必要
公式ドキュメントには次の記載があり、Windowsホストでは使えないと書いてあります。
Windows users: NFS folders do not work on Windows hosts. Vagrant will ignore your request for NFS synced folders on Windows.
ところが、なんとWindowsでNFS機能を使用できるプラグイン(vagrant-winnfsd
)がコミュニティに存在します!素晴らしすぎて感謝してもしきれません。
ホスト側がWindowsの場合は下記コマンドでプラグインを先にインストールしておいてください。
vagrant plugin install vagrant-winnfsd
NFS に変更する方法
NFSに変更するにはVagrantFileの共有ディレクトリの設定にあたる部分を変更する必要があります。
先ほどの公式ドキュメントに記載されていた通り、type: "nfs"
を追加するだけで使用できます。
例えば次のように設定します。
config.vm.synced_folder ".", "/var/www/src", type: "nfs"
尚、private_networkが必要です。IPは例ですが、静的IPアドレスだとトラブルがすくないです(.1はホスト側で予約されていますので.2以上にする必要があります)。
config.vm.network :private_network, ip: "192.168.2.2"
(とくにMac)ファイアウォールに引っかかりやすいので、うまく動作しない場合はファイアウォールの設定をご確認ください。
CSS や JavaScript が壊れてしまう場合
環境の組み合わせによっては、sendfileの影響でCSSやJavaScriptが壊れてしまう場合があります。その場合の対処方法はこちらをご確認ください。
シンボリックリンクが動作しない場合
Laravelでは、シンボリックリンクを貼らないといけない機能(ファイルストレージ)があります。
ホストがWindowsの環境では、なぜかシンボリックリンクが壊れてしまい利用できませんでした。
$ ls -l storage
lrwxrwxrwx 1 root root 0 Dec 24 02:12 storage -> ../../storage/app/public
$ cd storage
cd: no such file or directory: storage
vagrant-winnfsdプラグインの影響なのか、Windowsの影響なのかわかってはいません。
私は、Publicディレクトリのみ、標準の共有ファイルに設定しました。次のようなイメージです。
config.vm.synced\_folder ".", "/var/www/src", type: "nfs", rsync\_\_exclude: "./public"
config.vm.synced\_folder "./public", "/var/www/src/public"
これで、高速化しつつ、ファイルストレージも使用できる環境になりました。それでもLaravelは遅いですけどね…。