Drupal lightning-fast synced folders in Vagrant & Virtualbox

Tuesday, January 24th 2017 - Drupal - Drupal 7

Update : You can find a VM here : https://github.com/guix77/nfsguest (I'll add Drush and other tools later)

Developing websites inside virtual machines Vagrant and Virtualbox is great, but when it comes to Drupal, the synced folders can be horribly slow. Of course it is very well known that VBOXFS, the native synced method used by Vagrant, is slow. Thing is, Drupal (and some other web sites engines) has to parse a lot of files. Especially in development, if you need to run Drush tasks.

Vagrant NFS

I'm sure that you already changed it to NFS. On the project I'm working on these days, we have at about 200 modules. For some tasks, we run scripts like drush rr, drush cc all, drush fra for features and drush cc all. You can count at least 5 minutes for the script to run. But, if like me you are developing on Mac OS X, then, because of permission problems, you have to use BindFS between the Mac and the NFS. Then things become totally unmanagable. A script like this takes around 12 minutes to complete, and that is a no-way.

Other options

So I had a look at other options to sync my Drupal code folder with the VM. I tried Rsync and it's lightning-fast, since the files are copied from your host Drupal folder to the guest Drupal folder. PHP (and Apache2) in the VM has direct access to the files on its filesystem. Unfortunately, the sync is one-way ony, from your host to the guest. If you create new files in the VM, for instance if you flush the theme cache, if you use Drush fua (Features), or compile your LESS files with Gulp, then they won't be synced to your host folder. So I tried to use Unison with Vagrant, a 2 way sync technology. But I kept having issues. I guess that I could have tried to compile the exact same version on Mac OS X and on my Debian VM. But I didn't like too much the fact that it consumes twice the disk space (you have a copy on your host, and another on the guest, and they are synced). So I was preparing to switch back to Vagrant NFS synced folders, BUT not on my Mac OS X, on an old PC laptop with Ubuntu, in order to avoid using BindFS. Then I discovered a very simple, but elegant solution, that solves everything. Well I didn't invent it, I saw it after quite a while of researchs on the net. It is very rare and difficult to stumble on this solution, so I thought that would be worth of a blog article to share the idea.

NFS server on the VM guest !

The idea is to use NFS to share the Drupal code folder. But NOT like Vagrant does it ! Vagrant creates a NFS server in your host, and the development server inside the VM connects to the server as a client. The idea here is to MAKE THE CONTRARY : to create a NFS server inside of the VM, and to serve the folder to the host machine. In that way, all the files are still on the same filesystem as PHP and Apache2. Your local Drupal site becomes faster and your Drush tasks become WAY faster. When it took me at around 12 minutes to run my script on our project with Vagrant NFS and BindFS, I now run it in 1 minute and a half ! Waouw !

How to do it

In your Vagrant file, don't write ANY config.vm.synced_folder statment. Basicaly, just configure your Vagrant machine without access to the files from the host. What you need is to define a private network :

Vagrant.configure("2") do |config|
  config.vm.box = "debian/jessie64"
  config.vm.hostname = "devbox"
  config.vm.network "private_network", ip: "192.168.54.12"
end

Vagrant up, vagrant ssh to open a bash session on your VM guest. Install NFS server, on Debian/Ubuntu :

sudo apt-get install nfs-kernel-server

Then configure the Drupal folder export, by editing /etc/exports as root :

sudo nano /etc/exports

In the file, add a line :

/var/www/drupal_folder 192.168.54.1(insecure,rw,all_squash,anonuid=1000,anongid=1000)

Where :

  • 92.168.51.1 is automatically your host IP ont the private network defined in the Vagrantfile
  • insecure is only necessary for Mac OS X host machines
  • anonuid=1000 must be the id of the owner of /var/www/drupal_folder and anongid its group. I suggest to run Apache2 (or your other server) as vagrant/vagrant :
sudo sed -i "s/export APACHE_RUN_USER=www-data/export APACHE_RUN_USER=vagrant/" /etc/apache2/envvars
sudo sed -i "s/export APACHE_RUN_GROUP=www-data/export APACHE_RUN_GROUP=vagrant/" /etc/apache2/envvars

Restart the NFS server :

sudo service nfs-kernel server restart

That's it for the NFS server in the VM guest ! Let's go back to our dev host machine. Create a directory outside of the Vagrant machine folder :

cd ..
mkdir www

At last, let's mount /var/www/drupal_folder on our host : Mac OS X :

mount -t nfs 192.168.54.12:/var/www/drupal_folder www

Linux :

sudo mount -t nfs 192.168.54.12:/var/www/drupal_folder www

That's it ! You now have a lightning-fast Drupal dev site, running Drush commands in 5 to 10 times quicker. Just don't forget to unmount the folder before halting the Vagrant machine.

Add new comment