Vagrant and NFS

One of the most useful features of Vagrant is that it has the ability to share files with the VMs it manages, which lets your team work with the tools they're used to while still getting the benefits of running the full production stack.

Steven Merrill, Director of Devops
#Development | Posted

One of the most useful features of Vagrant is that it has the ability to share files with the VMs it manages, which lets your team work with the tools they're used to while still getting the benefits of running the full production stack.

It can share those files from the host (the machine running VirtualBox and Vagrant) to the guest (the virtualized Linux machine) via VirtualBox's built-in file sharing on Mac, Windows, or Linux. When run on Linux or Mac hosts, it can also share files to the guest via NFS. NFS performs much better for sharing large numbers of files on a Linux or Mac host, which is well documented in the excellent Vagrant documentation. In addition, remember that the directory with the Vagrantfile in it will be shared with VirtualBox's built-in file sharing, so we probably don't want to put our docroot right in that directory.

As a result, we usually set up our project directories to look like the following with the docroot one level up from the directory with the Vagrantfile in it. (The docroot can be a symlink or a real copy of the docroot - it is in the .gitignore file so it won't be committed.)

Vagrant setup with the treehouseagency.com folder on the same level as the folder that contains the Vagrantfile

There's a few gotchas with using NFS folders:

  • If you try to export a symlink, nfsd will complain. You need to dereference any symlinks before they are put in /etc/exports. The sample code below avoids that.
  • Vagrant automatically uses NFS's mapall to ensure that all file access on the guest maps to your user and group on the host. This will mean that the users and groups may look wrong on the VM (and and chown or chgrp commands will fail), but software on the VM will be able to write to everything in that directory.

Finally, here's some stub code for setting up a vagrant project with a docroot one level up. It takes care of dereferencing any symlinks and sharing the docroot with the guest. It will share it with NFS if the host is a Linux or Mac machine.

  1. # Set up some variables relating to which path Vagrant will try to share
  2. # with the VM.
  3. require ‘pathname’
  4. $docroot_name = "treehouseagency.com"
  5. $docroot_path = ""
  6. # Test that the directory to be shared is in the right place and if it is,
  7. # calculate the fully dereferenced path (since NFS exports will fail if you
  8. # try to specify the path to a symlink.)
  9. if !File.exists?("../#{$docroot_name}") then
  10. puts "Please put the ‘%s’ directory (or a symlink to it) in the ‘%s/’ directory." %
  11. [$docroot_name, Pathname.new("../").realpath.to_s]
  12. exit 1
  13. else
  14. $docroot_path = Pathname.new("../#{$docroot_name}").realpath.to_s
  15. end
  16.  
  17. Vagrant::Config.run do |config|
  18.  
  19. # Add in the rest of your config here.
  20.  
  21. config.vm.share_folder "tha-docroot", "/tha-docroot", $docroot_path, :nfs => (RUBY_PLATFORM =~ /linux/ or RUBY_PLATFORM =~ /darwin/)
  22. end

Enjoy!

Steven Merrill

Director of Devops