# How to use Laravel Homestead on Windows

In one of the more frustrating experiences I have had with Windows, I recently spent over an hour or two trying to get Laravel Homestead on Windows to play nicely. And there’s still room for improvement, but here is what can be done.

## The Problem with Laravel Homestead on Windows

This is a general problem with modern PHP applications, with or without virtualisation, and is not specific to Laravel. Modern frameworks in development mode result in hundreds of file modification time checks and other file system tasks that Windows does not deal well with. What Unix-like systems do in under 10ms takes an order or two of magnitude longer on Windows. Adding virtualisation into the equation slows request times further. Detailed in this post are instructions on getting everything up and going; improving folder sharing between Windows and Laravel Homestead; and finally some general PHP tweaks.

## Getting Laravel Homestead up and running

First of all, I am assuming you have followed the documentation on Laravel Homestead and therefore have run vagrant up and can see your application in your web browser on the host machine.

If you haven’t got this far, there are a couple of stumbling blocks and here are some pointers to help you:

• Paths such as ~/.ssh or ~/.homestead are not traditional Windows paths. Nevertheless, for the purposes of the software used, they resolve, and where they resolve to is your user folder, e.g. C:\Users\Jane if you are using Windows 7 or newer.
• Windows Explorer doesn’t let you create folders with a “.” (dot) at the start of the name as far as I can tell. The easiest solution is to use the Command Prompt. For example, mkdir -p c:\Users\Jane\.homestead
• If you do not have Unix style commands such as bash available on your Command Prompt, use “Git Bash”, a tool that is available after installing Git for Windows. The Laravel documentation mentions alternatives. When installing Git, you can select the option below during the install process to have access to Unix tools in the standard Windows Command Prompt:
• If you still cannot load your app, make sure you have updated your hosts file. This is typically located in c:\windows\system32\drivers\etc\hosts. Note that the hosts file is in a hidden folder, and that the file may be write protected if you are not an administrator. The format here is: 192.168.10.10 laravel.app
• When accessing the Vagrant box using SSH and you are using a non-default private key location, you can specify it, for instance: ssh [email protected] -p 2222 -i c:\Users\Jane\.ssh\homestead_rsa

## File sharing between Windows and Laravel Homestead

The default way that the virtualisation setup and how Laravel Homestead is configured results in very slow file operations. To remedy this, we first make some configuration tweaks to mount NFS shares. Add the bold lines below to the corresponding spots on your Homestead config, e.g. c:\Users\Jane\.homestead\Homestead.yaml:

  folders:
- map: c:\server\htdocs
to: /home/www
type: "nfs"

YAML files have strict rules with indenting. Make sure you indent the lines with spaces only, no tabs. Otherwise, you will get errors thrown when trying to start your Vagrant box such as:

C:/Hashicorp/Vagrant/embedded/lib/ruby/2.0.0/pysch.rb:205:in parse': (<unknown>): found a tab character that violate intendation while scanning a plain scalar at line 14 column 11 (Pysch:SyntaxError)

To make use of NFS style file sharing, you also need to install two Vagrant plugins. From a Command Prompt, run the following commands:

vagrant plugin install vagrant-vbguest
vagrant plugin install vagrant-winnfsd

Finally, in the folder where Homestead was installed, open c:\path\to\Homestead\scripts\homestead.rb and add the following somewhere in the def Homestead.configure block:

    # Sort folders to keep vagrant-winnfsd happy
settings["folders"].sort! { |a,b| a["map"].length <=> b["map"].length }

# Add synced folders using NFS
settings["folders"].each do |folder|
config.vm.synced_folder folder["map"], folder["to"],
id: folder["map"],
:nfs => true,
:mount_options => ['nolock,vers=3,udp,noatime']
end

Now you can start your Vagrant box. Destroy the current Vagrant instance if there is one.

cd c:\path\to\Homestead
vagrant destroy
vagrant up

## PHP configuration tweaks and opcode caching

By default, there is no opcode caching on a PHP install, as well as some other general tweaks that should be done when using frameworks such as Laravel or Symfony, regardless of operating system or whether virtualisation is or isn’t used.

These changes are to be made on the guest machine, so ssh into your vagrant box, for example:

ssh [email protected] -p 2222 -i c:\Users\Jane\.ssh\homestead_rsa

Edit /etc/php7.0/fpm/php.ini with your favourite editor and modify the following:

;realpath_cache_size = 16 (old value)
realpath_cache_size = 4M

If your Homestead instance is not running PHP 7, you will need to modify the path to the php.ini file.

Enable PHP opcache by editing /etc/php5/mods-available/opcache.ini:. Make sure to check that the path to opcache.so is correct, and if it is not, find the correct path by running find /usr/lib -name opcache.so

zend_extension=/usr/lib/php5/20131226/opcache.so
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 4000
opcache.revalidate_freq = 1
opcache.validate_timestamps = on
opcache.fast_shutdown = 1

Finally, restart the web server.

sudo service nginx restart
cd /path/to/app
php artisan cache:clear`

## Conclusion

Typical results are a 5-10x speed improvement. For example, 2:00s load times reducing to 300ms. Further improvements can be made by:

• using HHVM, see the relevant documentation for how to set a site as HHVM in your Homestead config and how to serve sites as HHVM in Vagrant.
• keeping a copy of all the files on the virtual machine. Unless you no longer want to make changes to your project on the host machine, this will require syncing files using rsync via Cygwin or syncing functionality of a capable IDE or an alternative method.