rsync in Vagrant 1.5 improves file performance and Windows usage

I've been using Vagrant for almost all development projects for the past two years, and for projects where I'm the only developer, Vagrant + VirtualBox has worked great, since I'm on a Mac. I usually use NFS shared folders so I can keep project data (Git/SVN repositories, assets, etc.) on my local computer, and share them to a folder on the VM, and not suffer the performance penalty of using VirtualBox's native shared folders.

However, this solution only scaled well to other Mac and Linux users with whom I shared development responsibilities. Windows users were left in a bit of a lurch. To extend an olive branch, I hackishly added SMB support by installing and configuring an SMB share from within the VM only on windows hosts, so Windows devs could mount the SMB share and work on files in their native editors.

This solution was pretty shoddy, as SMB performance isn't amazing (searching across a directory with a couple thousand files is slow). Not only that, since the folder was shared from within the VM to the host machine, Git and other file operations were much easier to do within the machine, meaning Windows users had to learn some linux basics and use vagrant ssh quite often.

While Vagrant 1.5 also threw a few bones to Windows users in the form of Hyper-V support and native SMB shared folder support, what really excited me (for both Mac/Linux and Windows use) was rsync shared folder support.

rsync shared synced folders

Accessing files on VirtualBox's native VM file system is the fastest way to use complex, file-heavy applications like Drupal. I've tested native shared folders, SMB shared folders (not using Vagrant's method, but the performance should be similarly disappointing), native filesystem storage (the fastest), and NFS shared folders (noticeably slower than native, but not by much, and kludgy to get set up). By far, the simplest and fastest way of handling files in a VM is through use of the native filesystem. But until Vagrant 1.5, this was also a bit kludgy.

With Vagrant 1.5's rsync synced folder support, setup is easy, performance is blazing fast, one sharing method works on both Mac, Linux, and Windows. The only downsides (and these are minor) is that the initial vagrant up takes a little longer, since the first time it has to rsync your entire shared folder to the VM, basically doubling your project's disk space usage, and you have to run vagrant rsync (for ad-hoc syncing) or vagrant rsync-auto (for continuous syncing) while the VM is running. But since most codebases aren't too large, space/extra time for the initial sync is usually a non-issue, and vagrant rsync-auto doesn't seem to be too processor/disk intense after the first minute or two.

Before 1.5, my typical Vagrantfile had a section like the following:

if is_windows
  # - run a shell provisioner which runs ansible provisioner within vm
  # - in provisioner, install samba and configure a share
  # - rely on user to connect to share manually
else
  # - run ansible provisioner
  # - add a normal shared folder
  # - rely on user to comment out shared folder and uncomment nfs shared folder
  #   after the first `vagrant up`
end

It was fairly messy, though I was proud of the solution in the end—it was the best possible scenario for our particular use case pre-1.5.

Now, I have the following:

if is_windows
  # - run a shell provisioner which runs ansible provisioner within vm
else
  # - run ansible provisioner
end
# create an rsync synced folder for everyone

What does the shared folder setup look like, inside a Vagrantfile? It's really simple:

# Set up a shared folder using a path defined in the user's environment.
shared_folder_path = ENV['XYZ_SHARED_FOLDER_PATH'] ? ENV['XYZ_SHARED_FOLDER_PATH'] : "~/Sites/xyz"

config.vm.synced_folder shared_folder_path, "/xyz",
  # Tell Vagrant to use rsync for this shared folder.
  type: "rsync",
  rsync__auto: "true",
  rsync__exclude: ".git/",
  id: "shared-folder-id"

The shared_folder_path was added so team members could stick their code repositories wherever they liked, rather than be forced to put their repos in one rigid location, or hack the shared/version-controlled Vagrantfile. This is especially helpful when working between platforms, as Windows pathing is much different than Mac/Linux.

Comments

First: please, change this do @disqus.

Maybe useful say that cygwin is a requirement to make rsync and vagrant run normal in Windows.