6
6

More than 5 years have passed since last update.

Play Frameworkのauto-reloadingは、Vagrantのsynced folderで効かなかった

Last updated at Posted at 2015-05-24

VagrantのUbuntu環境で、Play Frameworkを使ったアプリの開発をしたいと思い試しています。

Playはソースコードが更新されると、自動的にコンパイルが走ってくれるauto-reloadingという機能が便利です。この機能をVagrantで試していて気がついたのですが、どうやら共有フォルダにあるソースコードは更新されてても、自動でコンパイルがかからないようです。controllersもviewsもどちらも変更してみましたが、やはりだめです。

そんなことはないんじゃないか?と思い、共有フォルダではないフォルダで試してみたら、ちゃんとreloadされていたので、原因は共有フォルダにあることが分かりました。

PlayKeys.playWatchServiceを試す → ダメ

いろいろググっていたら「Play 2.3.2 auto reload is not working on shared folder · Issue #3246 · playframework/playframework」というissueを見つけました。

PlayはOSレベルの機能でファイルの変更を検知しているとのことで、NFSなどはOSが対応していないので検知できないそうです。ここで提案されていた解決策は、次のコードをbuild.sbtに書くことです。

PlayKeys.playWatchService := play.sbtplugin.run.PlayWatchService.sbt(pollInterval.value)

これを追加すると500msの間隔で、ファイルをポーリングして検知できるようになるそうです。

これをbuild.sbtの最後にコピペして、念のためactivatorを終了して起動しなおし、activatorのコンソールでrunを実行しました。が、やはり更新を検出できないようです。

NFSにしてみる

さきほどのissueにリンクしているissue「Play 2.3.x not detecting changes to static resources in shared folder · Issue #4208 · playframework/playframework」に気づきました。こちらの課題を報告している方が、Vagrantの共有フォルダの設定がNFSで解決したそうなので、NFSにしてみます。

Vagrantfileに次を追記して

Vagrantfile
  config.vm.synced_folder ".", "/vagrant", type: "nfs"

Vagrantを起動しなおします。

vagrant reload

ちなみに、Vagrantfile全体としてはこんなふうになっています。

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "shouldbee/ubuntu-14.04-with-docker"
  config.vm.box_version = "0.5"
  config.vm.synced_folder ".", "/vagrant", type: "nfs"

  host = RbConfig::CONFIG['host_os']

  case host
  when /darwin/ # mac
    cpus = `sysctl -n hw.ncpu`.to_i
  when /linux/
    cpus = `nproc`.to_i
  else
    cpus = 2
  end

  config.vm.provider "vmware_fusion" do |v|
    v.vmx["memsize"] = "512"
    v.vmx["numvcpus"] = cpus
  end
end

起動したら、activatorを実行して、

vagrant ssh
./activator
run

ソースコードを変更してみます。が、だめでした。

Vagrantの共有フォルダの設定を変更してみます。

  config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ["lookupcache=none"]

Vagrantを再起動して、試します。

vagrant reload
vagrant ssh
./activator
run

やはり、ソースコードを更新しても検知されませんでした。

~run → 遅い

今度はPlayのauto-reloadingを使うのは諦めて、~runしてみることにしました。そうしたところ、コンパイルは自動的に行われるようになりましたが、Playで起動しているサーバには反映されないようで、一旦Ctrl+Dを押してはじめてサーバが再起動して反映されるようでした。これでも、使えないことはないですが、Ctrl+Dを押さないと行けないのと、起動の処理自体に5〜10秒かかるが繰り返しになってくるとストレスになりそうです。

情報求む

うまい解決策があれば教えてもられると嬉しいです :bow:


[2015-05-25]追記

rsyncを試してみた

Vagrantのrsyncファイル共有機能を使って、Playのプロジェクトを同期するのを試してみました。Vagrantfileには同期したいプロジェクトの指定します。

Vagrantfile
  config.vm.synced_folder ".", "/new-ui", type: "rsync",
    rsync__exclude: [
      "/.idea/",
      "/.idea_modules/",
      "/project/project/",
      "/project/target/",
      "/target/",
    ]

これを設定したら、vagrant reloadで再起動します。その後、同期が常に行われるように、もうひとつターミナルを開いてvagrant rsync-autoを実行しておきます。

rsyncなら普通のファイルシステムにソースコードを配置できるので、予想通りPlayのauto-reloadingが動きました。が、VMの性能の壁があり、僕の環境では、ホストマシンのMacでは1秒程度でリロードが終わるのに対して、rsync先のゲストマシンでは20〜30秒程度かかってしまうようです。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6