vagrant-fsevents
Activatable filesystem change forwarding to your Vagrant VM.
Problem this solves
When developing inside VirtualBox-based VMs with synced folders, filesystem events in the host system do not propagate to processes running inside the VM. This causes difficulty for some development environments, particularly when using packagers such as Webpack, as they do not update/rebuild in response to editor changes.
There are a number of partial solutions in the wild, but none are perfect in all
circumstances. This project builds on vagrant-fsnotify
by
@adrienkohlbecker to provide a simple on-demand, low resource, and highly
transparent solution. It is particularly effective for a standard development
VM which is used widely by multiple teams where perhaps only a few people even
need filesystem event forwarding, and it's not desirable to have an always-on
solution that hogs system resources.
Mechanism
vagrant-fsevents
runs a process listening for filesystem changes on the host
that affect shared folders, and forwards them to the VM as shell commands such
as touch
(and rm
, as appropriate) using Vagrant's VM administration API.
Caveats
Inconveniently, while filesystem events are not properly forwarded into the VM, they're forwarded back out without issue, so every time this plugin triggers an update in the VM, a second filesystem event is fired in the host system. To prevent the obvious infinite-loop issue this could cause, a minimum 2-second per-file dead-zone is used after each update event (with additional time for updates with many files changed)
This is unfortunately only a partial solution, and large filesystem changes such as checking out another git branch can still cause issues such as infinite notification loops and accidental creation of blank files that should have been removed. However, these issues are usually minor, easily fixed via git, and can be entirely avoided by killing the monitor process before major changes.
Installation
vagrant-fsevents
is a Vagrant plugin and can be installed by
running:
$ vagrant plugin install vagrant-fsevents
Vagrant version 1.7.3 or greater is required.
Usage
Basic setup
In Vagrantfile
synced folder configuration, add the fsevents: true
option. For example, in order to enable vagrant-fsevents
for the the default
/vagrant
shared folder, add the following:
config.vm.synced_folder ".", "/vagrant", fsevents: true
When the guest virtual machine is up, run the following:
$ vagrant fsevents
This starts the long running process that captures filesystem events on the host and forwards them to the guest virtual machine.
Multi-VM environments
In multi-VM environments, you can specify the name of the VMs targeted by
vagrant-fsevents
using:
$ vagrant fsevents <vm-name-1> <vm-name-2> ...
Excluding files
To exclude files or directories from being watched, you can add an :exclude
option, which takes an array of strings (matched as a regexp against relative
paths):
config.vm.synced_folder ".", "/vagrant", fsevents: true,
exclude: ["path1", "some/directory"]
This will exclude all files inside the path1
and some/directory
. It will
also exclude files such as another/directory/path1
.
Including files
By default, the entire directory tree of the synced folder on the host machine
is watched. However, there are potential issues with symlinks
that can arise from this approach, so until a more robust fix is in place you
can work around symlink issues by overriding the default watch path(s) with the
:include
option. This takes an array of strings (as relative paths) to folders
which must exist when the watch begins (no regexp support), and replaces the
default synced_folder path with these individual folder paths.
config.vm.synced_folder ".", "/vagrant", fsevents: true,
include: ["./src"]
This will watch only the files inside src
, ignoring all other files and
folders in the synced path.
Guest path override
If your actual path on the VM is not the same as the one in synced_folder
, for
example when using vagrant-bindfs
, you can use the
:override_guestpath
option:
config.vm.synced_folder ".", "/vagrant", fsevents: true,
override_guestpath: "/real/path"
This will forward a notification on ./myfile
to /real/path/myfile
instead of
/vagrant/myfile
.
Select filesystem events
By default, when the :fsevents
key in the Vagrantfile
is configured with
true
, all filesystem events are forwarded to the VM (creation, modification,
and removal). If, instead, you want to select only some of those events to be
forwarded (e.g. you don't care about file removals), you can use an Array of
Symbols among the following options: :added
, :modified
and :removed
.
For example, to forward only added files events to the default /vagrant
folder, add the following to the Vagrantfile
:
config.vm.synced_folder ".", "/vagrant", fsevents: [:added]
Original work
This plugin was originally vagrant-fsnotify
by @adrienkohlbecker,
but was renamed to facilitate continued development.
This plugin used vagrant-rsync-back
by @smerill and the
Vagrant source code as a starting point.