A few months ago, I went to DockerCon as a Microsoft representative. While I was there, I had the chance to ask developers about their favorite tools.
The most common tool mentioned (outside of Docker itself) was Vagrant. This was interesting — I was familiar with Vagrant, but I’d never actually used it. I decided that needed to change. Over the past week or two, I took some time to try it out. I got everything working eventually, but I definitely ran into some issues on the way.
My pain is your gain — here are my tips and tricks for getting started with Vagrant on Windows 10 and Hyper-V.
Tip 1: Install Hyper-V
- 1 Tip 1: Install Hyper-V
- 2 Tip 2: Set Up Networking Correctly
- 3 Tip 3: Use the Hyper-V Provider
- 4 Tip 4: Add the basics to your Vagrantfile
- 5 Trick 5: Shared folders uses SMBv1 for hashicorp/precise64
- 6 Tip 6: Enable Nifty Hyper-V Features
- 7 Tip 7: Filter for Hyper-V compatible boxes on Vagrant Cloud
- 8 Tip 8: Default to the Hyper-V Provider
- 9 Wrapping Up
For those new to Hyper-V, make sure you’ve got Hyper-V running on your machine. Our official docs list the exact steps and requirements.
Tip 2: Set Up Networking Correctly
Vagrant doesn’t know how to set up networking on Hyper-V right now (unlike other providers), so it’s up to you to get things working the way you like them.
There are a few NAT networks already created on Windows 10 (depending on your specific build). Layered_ICS should work (but is under active development), while Layered_NAT doesn’t have DHCP. If you’re a Windows Insider, you can try Layered_ICS. If that doesn’t work, the safest option is to create an external switch via Hyper-V Manager. This is the approach I took. If you go this route, a friendly reminder that the external switch is tied to a specific network adapter. So if you make it for WiFi, it won’t work when you hook up the Ethernet, and vice versa.
Tip 3: Use the Hyper-V Provider
When you install your first box, add –provider :
vagrant box add hashicorp/precise64 --provider hyperv
And when you boot your first Vagrant environment, again, add –provider. Note: you might run into the error mentioned in Trick 4, so skip to there if you see something like “mount error(112): Host is down”.
vagrant up --provider hyperv
Tip 4: Add the basics to your Vagrantfile
Adding the provider flag is a pain to do every single time you run
vagrant up. Fortunately, you can set up your Vagrantfile to automate things for you. After running
vagrant init, modify your vagrant file with the following:
Vagrant.configure(2) do |config| config.vm.box = "hashicorp/precise64" config.vm.provider "hyperv" config.vm.network "public_network" end
One additional trick here:
vagrant init will create a file that will appear to be full of commented out items. However, there is one line not commented out:
Make sure you delete that line! Otherwise, you’ll end up with an error like this:
Bringing machine 'default' up with 'hyperv' provider... ==> default: Verifying Hyper-V is enabled... ==> default: Box 'base' could not be found. Attempting to find and install... default: Box Provider: hyperv default: Box Version: >= 0 ==> default: Box file was not detected as metadata. Adding it directly... ==> default: Adding box 'base' (v0) for provider: hyperv default: Downloading: base default: An error occurred while downloading the remote file. The error message, if any, is reproduced below. Please fix this error and try again.
For the image used in the “Getting Started” guide (hashicorp/precise64), Vagrant tries to use SMBv1 for shared folders. However, if you’re like me and have SMBv1 disabled, this will fail:
Failed to mount folders in Linux guest. This is usually because the "vboxsf" file system is not available. Please verify that the guest additions are properly installed in the guest and can work properly. The command attempted was: mount -t cifs -o uid=1000,gid=1000,sec=ntlm,credentials=/etc/smb_creds_e70609f244a9ad09df0e760d1859e431 //10.124.157.30/e70609f244a9ad09df0e760d1859e431 /vagrant The error output from the last command was: mount error(112): Host is down Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
You can check if SMBv1 is enabled with this PowerShell Cmdlet:
If you can live without synced folders, here’s the line to add to the vagrantfile to disable the default synced folder.
config.vm.synced_folder ".", "/vagrant", disabled: true
If you can’t, you can try installing cifs-utils in the VM and re-provision. You could also try another synced folder method. For example, rsync works with Cygwin or MinGW. Disclaimer: I personally didn’t try either of these methods.
Tip 6: Enable Nifty Hyper-V Features
Hyper-V has some useful features that improve the Vagrant experience. For example, a pretty substantial portion of the time spent running
vagrant up is spent cloning the virtual hard drive. A faster way is to use differencing disks with Hyper-V. You can also turn on virtualization extensions, which allow nested virtualization within the VM (i.e. Docker with Hyper-V containers). Here are the lines to add to your Vagrantfile to add these features:
config.vm.provider "hyperv" do |h| h.enable_virtualization_extensions = true h.differencing_disk = true end
There are a many more customization options that can be added here (i.e. VMName, CPU/Memory settings, integration services). You can find the details in the Hyper-V provider documentation.
Tip 7: Filter for Hyper-V compatible boxes on Vagrant Cloud
Tip 8: Default to the Hyper-V Provider
While adding the default provider to your Vagrantfile is useful, it means you need to remember to do it with each new Vagrantfile you create. If you don’t, Vagrant will trying to download VirtualBox when you
vagrant up the first time for your new box. Again, VirtualBox doesn’t work alongside Hyper-V, so this is a problem.
PS C:vagrant> vagrant up ==> Provider 'virtualbox' not found. We'll automatically install it now... The installation process will start below. Human interaction may be required at some points. If you're uncomfortable with automatically installing this provider, you can safely Ctrl-C this process and install it manually. ==> Downloading VirtualBox 5.0.10... This may not be the latest version of VirtualBox, but it is a version that is known to work well. Over time, we'll update the version that is installed.
You can set your default provider on a user level by using the VAGRANT_DEFAULT_PROVIDER environmental variable. For more options (and details), this is the relevant page of Vagrant’s documentation.
Here’s how I set the user-level environment variable in PowerShell:
[Environment]::SetEnvironmentVariable("VAGRANT_DEFAULT_PROVIDER", "hyperv", "User")
Again, you can also set the default provider in the Vagrant file (see Trick 3), which will prevent this issue on a per project basis. You can also just add
--provider hyperv when running
vagrant up. The choice is yours.
Those are my tips and tricks for getting started with Vagrant on Hyper-V. If there are any you think I missed, or anything you think I got wrong, let me know in the comments.
Here’s the complete version of my simple starting Vagrantfile:
# -*- mode: ruby -*- # vi: set ft=ruby : # All Vagrant configuration is done below. The "2" in Vagrant.configure # configures the configuration version (we support older styles for # backwards compatibility). Please don't change it unless you know what # you're doing. Vagrant.configure("2") do |config| config.vm.box = "hashicorp/precise64" config.vm.provider "hyperv" config.vm.network "public_network" config.vm.synced_folder ".", "/vagrant", disabled: true config.vm.provider "hyperv" do |h| h.enable_virtualization_extensions = true h.differencing_disk = true end end