I'm a huge fan of streamlined development environments. I started out using XAMPP because it was self-contained (or so I thought).

As I continued to build up my environment, I upgraded to Varying Vagrant Vagrants  (VVV) - a virtual machine-based PHP development environment catered specifically to WordPress development. For the longest time, VVV was more than enough for my development needs.

But things often change.

Windows Development

From time to time, I've been known to take a break from PHP development to hack on code for Windows devices. I enjoy writing C#, and the intuitive nature of Visual Studio is something open source IDEs are still struggling to emulate.

A few weeks ago, I tried my hand at Windows Phone development.[ref]Actually, I was trying to debug a website and just needed a Windows Phone emulator since mocking a phone environment in Internet Explorer wasn't quite cutting it.[/ref] Unfortunately, there was a conflict between VirtualBox - the virtualization tool of choice for VVV - and Windows development.

The Windows emulators use Hyper-V, the virtualization tool built into Windows Professional. You cannot run two virtualization stacks in parallel.

At the time, this meant I had to enable Hyper-V and reboot (or disable Hyper-V and reboot) every time I wanted to switch from WordPress to Windows development. Considering I use these tools to optimize my workflow, the endless rebooting became annoying.

I wanted something smoother.


As of version 1.5, Vagrant supports using Hyper-V as a provider (and as a drop-in replacement for VirtualBox). It took me a little trial and error to set up, but this weekend I managed to port my entire WordPress development stack not just to a new machine, but also to a new virtualization provider.

Step 1

The first step is to swap out the provider itself. In VVV's Vagrantfile, we define the provider on line 14. Just replace [cci]:virtualbox[/cci] with [cci]:hyperv[/cci] and you're good.

To be extra safe (sometimes Vagrant ignores the setting), I also add a [cci]--provider=hyperv[/cci] flag when I [cci]vagrant up[/cci] for the first time. Once provisioned, the flag is unnecessary; but it's a good sanity check to be explicit with what you're doing.

You'll also want to remove the [cc]v.customize[/cci] lines beginning around line 15 (i.e. [cci]v.customize ["modifyvm", :id, "--memory", 512][/cci]) entirely as they will break Hyper-V (and have no effect in the first place).

Step 2

There isn't a precise32 box for Hyper-V[ref]I realize that VVV is now using Trusty 64, but the older version used Precise 32, so I'm sticking with that branch for now. Once someone produces a Hyper-V box for Trusty 64 I'll upgrade to that.[/ref], so I upgraded to the 64-bit version provided by Hashicorp.  First, you'll need to use [cci]vagrant box add hashicorp/precise64[/cci] to cache the virtual machine in your system. Then you'll need to update line 29 of the Vagrant file to reference "hashicorp/precise64" as well.

When you add the box, Vagrant may or may not ask you which provider to download. Remember, we're working with HyperV, so select appropriately.

Step 3

The biggest thing people have complained about regarding VVV is the slowness of the database, so the major change I've made is to not mount the [cci]/data[/cci] directory to my local system. Data will stay entirely within the virtual machine and there's no file sharing slowness associated with reading/writing MySQL.

I also updated the bundled [cci]my.cnf[/cci] to add [cci]innodb_file_per_table=1[/cci]. This isn't required for Hyper-V at all, but I've noticed that MySQL creates a large system tablespace file for all the things by default. I create (and delete) rather large databases for client testing and want to be able to reclaim that space once tables and databases disappear. Without this setting, that becomes ... difficult.

Step 4

The Hyper-V provider uses SMB shares to mount local directories within the virtual machine. This is similar to NFS on non-Windows systems, but comes with a couple of unique differences.

Primarily, the [cci]:mount_options[/cci] in our Vagrantfile will cause the SMB share to fail. Delete these extra entries and everything will proceed as expected.

Also know that, while provisioning, Vagrant will need your Windows credentials to make the share. For the moment, there's a bug somewhere that makes Windows password containing exclamation points (!) fail. The team is working on a patch, but for now it's just easier to change your password.

Other Notes

The only thing lacking from the Hyper-V setup today is the ability to bind a static IP address. During setup, you have to tell Vagrant which network adapter to use and Hyper-V automatically provisions a dynamic IP address. I've written and submitted a patch to the Hostsupdater project; just waiting for it to get bundled with the core plugin for future use.