Click to share! ⬇️

Install Laravel Homestead on Windows

Laravel is loads of fun, and the community around Laravel is what makes it so great. A lot of the top guns in the community from Taylor Otwell on down use OSX. That’s great since OSX has a more UNIX feel to it and almost all web projects are eventually deployed to some form of UNIX / Linux. Many of us don’t have the luxury of running a slick Macbook Pro or Macbook Air in our day to day routine due to corporate environments, or simply personal choice for using Windows as a desktop operating system. Up until now, we’ve been running Laravel right on top of WAMP, and you know what, it works perfect just like that. Lately however, Vagrant and VirtualBox are taking the world by storm, and with Taylor creating a dedicated local development environment for the community, we owe it to ourselves to check it out and get Homestead running on our local machines. This step by step guide will get us cooking with VirtualBox, Vagrant, and Homestead on our Windows 7 machine.


1. Install VirtualBox and Vagrant

We recently ranted about covered setting up Virtual Box and Vagrant on a Windows machine in this post. Follow the steps in that post to get you going. Keep this as a word of warning however. If you install the latest version of VirtualBox and have nothing but problems, uninstall the program from your computer. Then, go ahead and download version 4.3.12. This may get you where you need to be.


2. Launch Git Bash

If you have not done so already, install Git Bash. Once you have it installed you can launch the Git Bash program. Git Bash is fantastic because you can interact with folders on Windows using linux commands. In Git Bash run:

Chris@CHRIS-PC /c
`$ cd c:`

This will bring you right to the root drive of your machine, you can confirm with this command:

Chris@CHRIS-PC /c
`$ pwd`

This will display a result of /c to confirm our location.


3. Add The Homestead Vagrant Box To Vagrant

In the same Git Bash terminal window, cd into the directory which holds Vagrant. We had installed Vagrant into C:/vagrant in a prior episode, so we’ll use that location. We’ll also add the Laravel Vagrant Box to Vagrant.

Chris@CHRIS-PC /c
`$ cd vagrant`
Chris@CHRIS-PC /c/vagrant
`$ vagrant box add laravel/homestead`
==> box: Loading metadata for box ‘laravel/homestead’
box: URL: https://atlas.hashicorp.com/laravel/homestead
==> box: Adding box ‘laravel/homestead’ (v0.2.2) for provider: virtualbox
box: Downloading: https://atlas.hashicorp.com/laravel/boxes/homestead/versions/0.2.2/providers/v
irtualbox.box
box: Progress: 100% (Rate: 2834k/s, Estimated time remaining: –:–:–)
==> box: Successfully added box ‘laravel/homestead’ (v0.2.2) for ‘virtualbox’!


4. Clone The Laravel Homestead Repository

At this point, you’ll want to type $ cd .. to go right back to the C: prompt of your computer in Git Bash. In this Git Bash terminal window at this exact location run this command:

Chris@CHRIS-PC /c
`$ git clone https://github.com/laravel/homestead.git`
Cloning into ‘homestead’…
remote: Counting objects: 441, done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 441 (delta 6), reused 5 (delta 1)
Receiving objects: 100% (441/441), 64.72 KiB | 0 bytes/s, done.
Resolving deltas: 100% (235/235), done.
Checking connectivity… done.

This will automatically create the C:/homestead directory for you and download all of the homestead files into this folder. We need to understand what this folder accomplishes for us so let’s examine.

init.sh

First up is the init.sh file. This file contains the following contents:

#!/usr/bin/env bash

mkdir -p ~/.homestead

cp src/stubs/Homestead.yaml ~/.homestead/Homestead.yaml
cp src/stubs/after.sh ~/.homestead/after.sh
cp src/stubs/aliases ~/.homestead/aliases

echo "Homestead initialized!"

Soon we will run this script so by looking at the contents, we can understand what it does. The first potential gotcha is the tilde character convention. If you look at the line mkdir -p ~/.homestead and say, “what the heck is that going to do?”, this is your answer. In windows the ~/ combination equates to C:/Users/{yourname} so after we run this command, we should have a folder located at something like C:/Users/{yourname}/.homestead. The next 3 lines simply copy the files from C:/homestead/src/stubs into C:/Users/{yourname}/.homestead.

Vagrantfile

This file contains the following contents:

require 'json'
require 'yaml'

VAGRANTFILE_API_VERSION = "2"

homesteadYamlPath = File.expand_path("~/.homestead/Homestead.yaml")
afterScriptPath = File.expand_path("~/.homestead/after.sh")
aliasesPath = File.expand_path("~/.homestead/aliases")

require_relative 'scripts/homestead.rb'

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
	if File.exists? aliasesPath then
		config.vm.provision "file", source: aliasesPath, destination: "~/.bash_aliases"
	end

	Homestead.configure(config, YAML::load(File.read(homesteadYamlPath)))

	if File.exists? afterScriptPath then
		config.vm.provision "shell", path: afterScriptPath
	end
end

Note the line homesteadYamlPath = File.expand_path(“~/.homestead/Homestead.yaml”). This means that when we eventually try to launch the virtual machine, Vagrant is going to look in C:/Users/{yourname}/.homestead/Homestead.yaml in order to read the configuration options in that YAML file. If this file does not contain the right configuration, or if Vagrant can not locate the Homestead.yaml file, we’re dead in the water. This is why we’re examining how this all fits together.


5. Execute the init.sh script file

In the prior step, we learned just a little bit about the files contained in our homestead folder. We are now ready to actually execute the script contained like so.

Chris@CHRIS-PC /c
`$ cd homestead`
Chris@CHRIS-PC /c/homestead (master)
`$ bash init.sh`
Homestead initialized!


6. Create a LOCAL development folder and a LOCAL repository of Laravel

Before we configure our Homestead.yaml file, we need to create a local Laravel project in a local directory. It is these local files that you will actually load up in your IDE to edit and so on. As you do your work, these files will instantly sync to the Virtual Machine, which is really slick. In this example we’ll create a folder called localdev, and install a fresh copy of Laravel.

Chris@CHRIS-PC ~
`$ cd c:`
Chris@CHRIS-PC ~
`$ mkdir localdev`

Chris@CHRIS-PC /c
`$ cd localdev`

Chris@CHRIS-PC /c/localdev
`$ composer create-project laravel/laravel Laravel –prefer-dist`
Installing laravel/laravel (v4.2.11)
– Installing laravel/laravel (v4.2.11)
Downloading: connection… Downloading: 0%
Downloading: 100%

Created project in Laravel
Loading composer repositories with package information
Installing dependencies (including require-dev)
– Installing symfony/translation (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/security-core (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/routing (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 95%
Downloading: 100%

– Installing symfony/process (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing psr/log (1.0.0)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/debug (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/http-foundation (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/event-dispatcher (v2.6.3)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/http-kernel (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/finder (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/dom-crawler (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/css-selector (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/console (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/browser-kit (v2.5.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing swiftmailer/swiftmailer (v5.3.1)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing stack/builder (v1.0.3)
Downloading: connection… Downloading: 0%
Downloading: 35%
Downloading: 100%

– Installing predis/predis (v0.8.7)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing phpseclib/phpseclib (0.3.9)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing patchwork/utf8 (v1.1.26)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing nesbot/carbon (1.13.0)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing monolog/monolog (1.12.0)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing nikic/php-parser (v0.9.5)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing jeremeamia/superclosure (1.0.1)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing filp/whoops (1.1.3)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing ircmaxell/password-compat (v1.0.4)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing d11wtq/boris (v1.0.8)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing symfony/filesystem (v2.6.3)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing classpreloader/classpreloader (1.0.2)
Downloading: connection… Downloading: 0%
Downloading: 100%

– Installing laravel/framework (v4.2.16)
Downloading: connection… Downloading: 0%
Downloading: 100%

symfony/translation suggests installing symfony/config ()
symfony/translation suggests installing symfony/yaml ()
symfony/security-core suggests installing symfony/validator (For using the user password constraint)

symfony/security-core suggests installing symfony/expression-language (For using the expression voter)
symfony/routing suggests installing symfony/config (For using the all-in-one router or any loader)
symfony/routing suggests installing symfony/yaml (For using the YAML loader)
symfony/routing suggests installing symfony/expression-language (For using expression matching)
symfony/routing suggests installing doctrine/annotations (For using the annotation loader)
symfony/event-dispatcher suggests installing symfony/dependency-injection ()
symfony/http-kernel suggests installing symfony/class-loader ()
symfony/http-kernel suggests installing symfony/config ()
symfony/http-kernel suggests installing symfony/dependency-injection ()
predis/predis suggests installing ext-phpiredis (Allows faster serialization and deserialization of the Redis protocol)
phpseclib/phpseclib suggests installing pear-pear/PHP_Compat (Install PHP_Compat to get phpseclib working on PHP < 4.3.3.)
monolog/monolog suggests installing graylog2/gelf-php (Allow sending log messages to a GrayLog2 server)
monolog/monolog suggests installing raven/raven (Allow sending log messages to a Sentry server)
monolog/monolog suggests installing doctrine/couchdb (Allow sending log messages to a CouchDB server)
monolog/monolog suggests installing ruflin/elastica (Allow sending log messages to an Elastic Search server)
monolog/monolog suggests installing videlalvaro/php-amqplib (Allow sending log messages to an AMQP server using php-amqplib)
monolog/monolog suggests installing ext-amqp (Allow sending log messages to an AMQP server (1.0+ required))
monolog/monolog suggests installing ext-mongo (Allow sending log messages to a MongoDB server)
monolog/monolog suggests installing aws/aws-sdk-php (Allow sending log messages to AWS services like DynamoDB)
monolog/monolog suggests installing rollbar/rollbar (Allow sending log messages to Rollbar)
d11wtq/boris suggests installing ext-readline (*)
d11wtq/boris suggests installing ext-pcntl (*)
d11wtq/boris suggests installing ext-posix (*)
laravel/framework suggests installing doctrine/dbal (Allow renaming columns and dropping SQLite columns.)
Writing lock file
Generating autoload files
Generating optimized class loader
Compiling common classes
Compiling views
Application key [LZJ3ei4bGg6T9A7P50LMD99jzT1ADDdc] set successfully.


7. Configure SSH via Git Bash

We need to configure SSH. In this tutorial we already had it set up, but we’ll run it again to make sure you don’t miss a step. The takeaway is that you want to simply accept the defaults, since the folders and filenames that get created will be loaded in the Homestead.yaml file. The commands in the terminal will look a bit like this.

Chris@CHRIS-PC /c/localdev
`$ ssh-keygen -t rsa -C “you@homestead”`
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/Chris/.ssh/id_rsa):
/c/Users/Chris/.ssh/id_rsa already exists.
`Overwrite (y/n)? y`
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/Chris/.ssh/id_rsa.
Your public key has been saved in /c/Users/Chris/.ssh/id_rsa.pub.
The key fingerprint is:
27:1c:57:b7:63:17:d4:68:1a:7c:4f:4f:d3:b3:3a:72 you@homestead
The key’s randomart image is:

+--[ RSA 2048]----+
|           .. o+o|
|           .o.++*|
|        . .  =++*|
|       . o  .. +o|
|        S .   .  |
|         o . E   |
|            o .  |
|                 |
|                 |
+-----------------+

8. Configure Windows hosts file

This step takes care of the ability to create nice short domain names that will route to your development machine in the browser. The example we have followed so far is the convention of using homestead.app just like the official docs do, so we’ll set that up now. Understand that homestead.app is the actual domain name you type into your browser when you’re ready to test. So if everything goes well, by the time we finish this whole process, when we load http://homestead.app in a web browser, we’ll see our new Laravel installation working.

Make sure to open notepad.exe as administrator, then navigate to C:/Windows/System32/drivers/etc/hosts and add this 192.168.10.10 homestead.app to the file right at the end.

# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#	127.0.0.1       localhost
#	::1             localhost

127.0.0.1       localhost
192.168.10.10   homestead.app

9. Configure Homestead.yaml

We are now ready to configure the Homestead.yaml configuration file. Recall that Vagrant is going to be looking for this file in C:/Users/{yourname}/.homestead/Homestead.yaml so this is the file to open and edit.

Original Homestead.yaml

ip: "192.168.10.10"
memory: 2048
cpus: 1

authorize: ~/.ssh/id_rsa.pub

keys:
    - ~/.ssh/id_rsa

folders:
    - map: ~/Code
      to: /home/vagrant/Code

sites:
    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public

databases:
    - homestead

variables:
    - key: APP_ENV
      value: local

Modified Homestead.yaml

ip: "192.168.10.10"
memory: 2048
cpus: 1

authorize: ~/.ssh/id_rsa.pub

keys:
    - ~/.ssh/id_rsa

folders:
    - map: C:/localdev
      to: /home/vagrant/Code

sites:
    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public

databases:
    - homestead

variables:
    - key: APP_ENV
      value: local

This step is pretty important and there has been a fair amount of confusion as to how this works so we’ll drill right down here.

Folders

Notice that the only thing we changed is the map location in the folders: property. We are now telling Vagrant that we have a bunch of files and folders in C:/localdev on the Local Machine, and we want to automatically and instantly sync those files and folders to /home/vagrant/Code on the Virtual Machine.

Sites

This handles mapping our domain name to the folder which contains the site we want to load. So what the config file says here is that when we type homestead.app into the browser, this will map to /home/vagrant/Code/Laravel/public on the Virtual Machine. Since we had created a local Laravel project named Laravel in step 6, this all maps out perfectly. The reason is that as soon as the Virtual Machine boots, it is going to look in C:/localdev and see that there is a folder in it named Laravel. It will then instantly sync all files and folders, so the Virtual Machine will now also contain a folder named Laravel in it’s /home/vagrant/Code directory.


10. Launch The Virtual Machine

The moment of truth is here, we are now ready to launch the Virtual Machine. We can do so with vagrant up in the homestead directory from Git Bash.

Chris@CHRIS-PC /c/localdev
`$ cd c:/homestead`
Chris@CHRIS-PC /c/homestead (master)
`$ vagrant up`
Bringing machine ‘default’ up with ‘virtualbox’ provider…
==> default: Importing base box ‘laravel/homestead’…
==> default: Matching MAC address for NAT networking…
==> default: Checking if box ‘laravel/homestead’ is up to date…
==> default: Setting the name of the VM: homestead
==> default: Clearing any previously set network interfaces…
==> default: Preparing network interfaces based on configuration…
default: Adapter 1: nat
default: Adapter 2: hostonly
==> default: Forwarding ports…
default: 80 => 8000 (adapter 1)
default: 443 => 44300 (adapter 1)
default: 3306 => 33060 (adapter 1)
default: 5432 => 54320 (adapter 1)
default: 22 => 2222 (adapter 1)
==> default: Running ‘pre-boot’ VM customizations…
==> default: Booting VM…
==> default: Waiting for machine to boot. This may take a few minutes…
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default: Warning: Connection timeout. Retrying…
default: Warning: Remote connection disconnect. Retrying…
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest…
default: Removing insecure key from the guest if its present…
default: Key inserted! Disconnecting and reconnecting using new SSH key…
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM…
==> default: Setting hostname…
==> default: Configuring and enabling network interfaces…
==> default: Mounting shared folders…
default: /vagrant => C:/homestead
default: /home/vagrant/Code => C:/localdev
==> default: Running provisioner: file…
==> default: Running provisioner: shell…
default: Running: inline script
==> default: stdin: is not a tty
==> default: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1ThoVMH/PUHPpRyIRv+6FeGP
vahwMmHsli5l9neIP11wjSRs4P/9w6F85WGvnxGKEdPSvJ8qs53Z9F5FDaPVxYW87kEojYFolf6+
rc/4WKDjt3GUZTL/PzLwJgMRPdFzKBLglrb8nZ4NyrETCIdvwOkk6n51ywFsEyOlacvVCfe433r2
sqWgQ90xEtGlJS1Ar4UjbNe3iYwLczHd2bSQZ2IHctXfmOPpmDjXhQKT9uXIVqT+r1O+U+TatTLD
you@homestead
==> default: Running provisioner: shell…
default: Running: inline script
==> default: Running provisioner: shell…
default: Running: inline script
==> default: stdin: is not a tty
==> default: * Restarting nginx nginx
==> default: …done.
==> default: php5-fpm stop/waiting
==> default: php5-fpm start/running, process 2279
==> default: Running provisioner: shell…
default: Running: C:/Users/Chris/AppData/Local/Temp/vagrant-shell20150108-4152-pxseg2.sh
==> default: stdin: is not a tty
==> default: Warning: Using a password on the command line interface can be insecure.
==> default: Warning: Using a password on the command line interface can be insecure.
==> default: Running provisioner: shell…
default: Running: C:/Users/Chris/AppData/Local/Temp/vagrant-shell20150108-4152-1gm56mg.sh
==> default: stdin: is not a tty
==> default: Running provisioner: shell…
default: Running: inline script
==> default: stdin: is not a tty
==> default: Running provisioner: shell…
default: Running: inline script
==> default: stdin: is not a tty
==> default: php5-fpm stop/waiting
==> default: php5-fpm start/running, process 2393
==> default: Running provisioner: shell…
default: Running: inline script
==> default: stdin: is not a tty
==> default: Updating to version c58b7d917c65692eeb00c22b2fbaaa251cb390dc.
==> default: Downloading: connection…
==> default:
==> default: Downloading: 0%
==> default:
==> default:
==> default:
==> default: Downloading: 5%
==> default:
==> default: Downloading: 10%
==> default:
==> default: Downloading: 15%
==> default:
==> default: Downloading: 20%
==> default:
==> default: Downloading: 25%
==> default:
==> default: Downloading: 30%
==> default:
==> default: Downloading: 35%
==> default:
==> default: Downloading: 40%
==> default:
==> default: Downloading: 45%
==> default:
==> default: Downloading: 50%
==> default:
==> default: Downloading: 55%
==> default:
==> default: Downloading: 60%
==> default:
==> default: Downloading: 65%
==> default:
==> default: Downloading: 70%
==> default:
==> default: Downloading: 75%
==> default:
==> default: Downloading: 80%
==> default:
==> default: Downloading: 85%
==> default:
==> default: Downloading: 90%
==> default:
==> default: Downloading: 95%
==> default:
==> default: Downloading: 100%
==> default: Use composer self-update –rollback to return to version a422d67e2701860a44a4634f62f88b
58b8636468
==> default: Running provisioner: shell…
default: Running: C:/Users/Chris/AppData/Local/Temp/vagrant-shell20150108-4152-1ei726k.sh
==> default: stdin: is not a tty


You Made It!

That’s it folks! Visit http://homestead.app in your web browser and you will see the familiar splash screen like so.

Install Laravel Homestead on Windows

Click to share! ⬇️