我有一个相当嵌套的结构:
ubuntu/trusty64
正在运行... 每个图层的配置方式都是从上面的图层共享文件系统的一部分。这样:
config.vm.synced_folder
Vagrantfile
指令
-v
VOLUME
命令,如switch和Dockerfile
指令
这样我可以在我的工作站上进行开发,底部的Grails应用程序应该(理想情况下)检测更改并动态重新编译/重新加载。这是我在MacOSX上直接运行相同应用程序时常用的功能,但现在grails似乎完全不知道文件更改。当然,如果我使用编辑器(在Docker容器内)打开文件,它们确实已经更改,实际上如果我停止/重新启动grails应用程序,则会使用新代码。
我不知道grails如何实现监视策略,但如果它依赖于某些操作系统级别的功能,我怀疑文件更改通知会在链中的某处丢失。
任何人都知道可能是什么原因和/或我如何调试它?
答案 0 :(得分:1)
有两种方法可以检测文件更改(我知道):
轮询,表示以特定间隔检查文件夹中所有文件的时间戳。进行“近乎即时”的变化检测需要非常短的间隔。这是CPU和磁盘密集型的。
操作系统事件(Linux上的inotify,OS X上的FSEvents),由于文件操作通过操作系统子系统,因此可以检测到更改。这在CPU和磁盘上很容易。
网络文件系统(NFS)等不会生成事件。由于文件更改不通过客户操作系统子系统,因此操作系统不知道更改;只有操作系统进行更改(OS X)才知道它们。
Grails和许多其他File Watcher工具依赖于FSEvents或inotify(或类似)事件。
那该怎么办?考虑到可能产生的流量,在正常情况下“广播”从主机到所有访客的NFS更改是不切实际的。但是,我认为VirtualBox的股票应算作特殊例外...
弥合这一差距的机制可能涉及一个监视主机进行更改并在guest虚拟机上触发同步的进程。
查看这些文章,了解一些有趣的想法和解决方案,包括某种类型的rsync操作:
http://drunomics.com/en/blog/syncd-sync-changes-vagrant-box(Linux) https://github.com/ggreer/fsevents-tools(OS X)
与guest虚拟机(Docker)实例上的非NFS文件夹进行Rsync并具有I / O性能显着提高的额外优势。 VirtualBox的份额非常缓慢。
更新!
这就是我的所作所为。首先安装 lsyncd (OS X示例,http://kesar.es/tag/lsyncd/处的更多信息):
brew install lsyncd
在我的Mac上的Vagrant文件夹中,我创建了文件 lsyncd.lua :
settings {
logfile = "./lsyncd.log",
statusFile = "./lsyncd.status",
nodaemon = true,
pidfile = "./lsyncd.pid",
inotifyMode = "CloseWrite or Modify",
}
sync {
default.rsync,
delay = 2,
source = "./demo",
target = "vagrant@localhost:~/demo",
rsync = {
binary = "/usr/bin/rsync",
protect_args = false,
archive = true,
compress = false,
whole_file = false,
rsh = "/usr/bin/ssh -p 2222 -o StrictHostKeyChecking=no"
},
}
这样做是将我的Vagrant文件夹中的文件夹demo
同步到/home/vagrant/demo
中的来宾操作系统。请注意,您需要使用SSH密钥设置登录,以使此过程无摩擦。
然后,随着vagrant VM的运行,我启动了lsyncd进程。 -log Exec
是可选的;它将其活动记录到标准输出:
sudo lsyncd lsyncd.lua -log Exec
在流浪汉VM上,我在同步文件夹中启动了Grails(2.4.4):
cd /home/vagrant/demo
grails -reloading run-app
在IntelliJ上我的Mac上编辑了一个Controller类。它几乎立即触发lsyncd(延迟2秒),之后很快我确认Grails重新编译了这个类!
总结:
问题: Textmate触发lsyncd尚未识别的一种FSEvent,因此未检测到更改。不过,Vim和IntelliJ很好。
希望这有助于某人!花了一天时间来解决这个问题。
答案 1 :(得分:1)
我发现在容器中可见文件系统通知的最佳方法如下:
它可能不是最有效或最优雅的方式,但这种方式对容器的用户是透明的。不需要运行其他脚本。
未在较大的项目中测试,但在我的情况下,我没有意识到性能问题。
答案 2 :(得分:0)
Vagrant已经包含了一些用于rsync的选项,因此没有必要在主机上安装特殊程序。
在Vagrantfile中,我配置了rsync:
config.vm.synced_folder ".", "/vagrant", type: "rsync", rsync__exclude: [ "./build", ".git/" ]
然后在命令行中(在主机中)运行:
vagrant rsync
从主机到访客执行一次同步。
或
vagrant rsync-auto
检测到主机上的更改时,它将自动运行。
请访问https://eresearch.fidelity.com/eresearch/markets_sectors/sectors/si_performance.jhtml?tab=siperformance和Vagrant rsync Documentation