Setting up a Laravel Homestead box

Categories Uncategorised

I spend a lot of time in the Larachat Slack channel, and one of the most common questions/topics is getting Laravel running locally in a proper dev environment on their machine.

There are a few different moving parts that enable a local dev environment to work, it’s easy to see why new developers might get confused. I recently got hold of a spare Mac Mini, so I installed the new and shiny Mac OS High Sierra, and created a clean user account to write this ‘from scratch’ tutorial.

Prerequisites

Anyone should be able to follow along and create a local dev environment, but you will need to have some idea about how to use the command line to move around the file system and run basic commands. It’s also worthwhile making sure you have Mac’s developer tools installed.

We will be setting up a local Laravel install, using the Homestead Vagrant box, which runs on VirtualBox.

This article is up-to-date as of October 2017, using the following software and versions:

  • Mac OS 10.13.1 (High Sierra)
  • VirtualBox 5.1.28
  • Vagrant 2.0.0

Mac Developer Tools OS Upgrade

The Mac Mini I’m using for this tutorial already had Sierra, with developer tools installed. I ran the High Sierra upgrade, and the developer tools broke. This happened last time I ugpraded too, so if you’ve recently upgraded and found that things like git aren’t working, or your /usr/local/bin permissions are weird, follow this blog post and you should be good.

High Sierra and NFS

At the time of writing, NFS sharing is currently broken with Homestead, but there is a fix being trialled by the developers. If you’re using NFS, you may want to check for any updates around this.

1. Download and Install VirtualBox

In order to setup our local dev environment, we will make use of a virtual machine. VirtualBox is a piece of free, open source software by Oracle, and it runs on all of the major Operating Systems.

Download VirtualBox and run the packaged installer. Once complete, you then have the ability to host virtual machines on your computer (you may need to reboot).

2. Download and Install Vagrant

So, we already have the ability to run virtual machines – what do we need next? Well, in order to make it easier to reproduce an environment, we’ll make use of Vagrant. Whilst we could spin up a Linux virtual machine and spend an age configuring it manually, we can use automated tools to do 99% of the heavy lifting for us, and set the box up in a predictable way. This also means that you can share your ‘Vagrant Files’ and a friend or colleague can provision a virtual box which is identical to your own, all with a single command or two.

You can download Vagrant from their website, and again, run the binary installer.

3. Install Homestead

I mentioned above that using Vagrant, we can repeatedly and easily spin up virtual machines that are automatically configured from a base template. So, we need a template – this means installing the operating system, required software (PHP, nginx, MySQL, etc…) and configuring it all. Fortunately, we don’t need to start from scratch – we can use Homestead!

Homestead is a pre-configured Vagrant box: it is a Ubuntu box that runs PHP7, Nginx, MariaDB, Composer, Node and more (full list here).

In order to install it, run the following command: vagrant box add laravel/homestead

The download may take a few minutes, depending on your connection speed, and should go something like this:

Dev-Mac-Mini:~ dev$ vagrant box add laravel/homestead
==> box: Loading metadata for box 'laravel/homestead'
    box: URL: https://vagrantcloud.com/laravel/homestead
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.

1) parallels
2) virtualbox
3) vmware_desktop

Enter your choice: 2
==> box: Adding box 'laravel/homestead' (v3.1.0) for provider: virtualbox
    box: Downloading: https://vagrantcloud.com/laravel/boxes/homestead/versions/3.1.0/providers/virtualbox.box
==> box: Successfully added box 'laravel/homestead' (v3.1.0) for 'virtualbox'!

4. Setup Homestead

We’re now at a point where we have VirtualBox installed, which Vagrant can use to power virtual machines, and we have a Vagrant ‘template’ called Homestead – which will run our local development environment.

The next thing we need to do is setup our Homestead configuration. This will define what sites we have running on the box, as well as things like CPU/Memory resource limits.

Clone the Homestead repo

First we will clone the Homestead repo from GitHub which has all the relevant files, and then move to its directory:

Dev-Mac-Mini:~ dev$ git clone https://github.com/laravel/homestead.git ~/Homestead

Cloning into '/Users/dev/Homestead'...
remote: Counting objects: 2491, done.
remote: Compressing objects: 100% (31/31), done.
remote: Total 2491 (delta 22), reused 35 (delta 17), pack-reused 2443
Receiving objects: 100% (2491/2491), 454.94 KiB | 1.20 MiB/s, done.
Resolving deltas: 100% (1453/1453), done.

Dev-Mac-Mini:~ dev$ cd ~/Homestead
Dev-Mac-Mini:Homestead dev$ 

Configure Homestead.yaml

There is now a folder in your home directory called Homestead. For my development environment, I prefer to have a single Homestead box, and all of my projects live on it. It’s possible to create per-project Homestead machines, but this won’t be covered here (find more information on that here).

Run the following command to create the required files: bash init.sh

Open the Homestead.yaml file using Vi/Vim, Nano or a GUI editor, and copy the following:

---
ip: "192.168.10.10"
memory: 2048
cpus: 1
provider: virtualbox

authorize: ~/.ssh/id_rsa.pub

keys:
    - ~/.ssh/id_rsa

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

sites:
    - map: example.local
      to: /home/vagrant/code/example/public

databases:
    - example

From the top: we first assign an IP address to our machine, then give it some RAM and CPU. You are free to increase or decrease these, I normally stick with the defaults and increase them only as needed. For those on a less powerful machine, you can also lower the memory usage, but if you plan on using Nginx, PHP, MySQL and more, don’t lower it too much! Finally, we ensure the provider is set to virtualbox(Vagrant can use other virtualisation software too, not just VirtualBox).

Next we define our SSH keys, which will automatically be provisioned on to the box, allowing us to login over SSH like a normal server.

Note: If you don’t have SSH keys, type ssh-keygen in Terminal and hit enter a few times to create a passwordless key

Folder Mapping

Once running, you will have two operating systems running on your machine. Each of these has its own file structure. We will write our code on our local OS (Mac, in this case), but we want the Homestead box to serve these files. For this to work, we create a map.

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

sites:
    - map: example.local
      to: /home/vagrant/code/example/public

The folders directive specifies that we will have a folder called code on our Mac, in the home directory. On the Homestead box, this folder will be available at /home/vagrant/code. For our setup, you will only need one folders map, as all of our projects will go in to the local code folder.

Now Homestead knows where your files are, it needs to know where the public folder is (in order to serve Laravel), as well as what domain you want to use. I tend to use ‘.app’ or ‘.dev’ versions of the live site. So danwalker.dev would by development version of this website, pick whatever you’d like. The examplefolder in your ~/code folder doesn’t exist, but we’ll create that shortly.

Note: Google have updated Chrome recently to protect the .dev extension, ensuring HTTPS is used. For local projects, I know recommend using a different extension such as .local

Single Folder Map vs Per-Project

It was pointed out to me by someone in Larachat that using a single folder (~/code in our example) for multiple projects can cause performance issues in some cases, best practice is advised to do file mapping per project. Personally I haven’t seen any performance issues on my 2015 MacBook Pro (i5/8GB), but maybe on less powerful systems you will. I’ll continue to use one folder as it works for me and many others that I know, without issue. YMMV.

5. Edit /etc/hosts

We told Homestead to host a website with a domain of example.local, but this domain doesn’t exist or do anything right now. We need to add an override to our host machine so that the domain points to your virtual machine. We can do this by editing the /etc/hosts file (which requires sudo rights).

Dev-Mac-Mini:Homestead dev$ sudo nano /etc/hosts
Password:

192.168.10.10 example.local

6. Composer Setup

At this point, we’re almost good to go. All we need to do is create our Laravel project files!

To get started, change directory to your Homestead directory in the Terminal (i.e. cd ~/Homestead) and then simply vagrant up followed by vagrant ssh, and interact with Composer inside your virtual machine:

Dev-Mac-Mini:Homestead dev$ cd ~/Homestead
Dev-Mac-Mini:Homestead dev$ vagrant up

[output removed]

Dev-Mac-Mini:Homestead dev$ vagrant ssh vagrant@homestead:~$

You are now inside your Vagrant virtual machine. To exit just type exit, and to jump back in, just vagrant ssh again from the Homestead directory.

Note: It’s important to understand the relationship between your VM and your local machine. For example, your database is running inside the Vagrant VM, not on your local machine. When running database migrations with php artisan migrate commands, you will need to be inside your VM (in your project directory) to connect to the database.

The first thing we’ll add is the Laravel package using Composer – the PHP package manager:

vagrant@homestead:~$ composer global require "laravel/installer"

7. Create your Laravel project

Now we’ll create that ~/code directory we discussed earlier, and add our example project, all from within our VM:

vagrant@homestead:~$ mkdir code; cd code
vagrant@homestead:~/code$ laravel new example.local
Crafting application...
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 68 installs, 0 updates, 0 removals       
  - Installing laravel/framework (v5.5.13): Downloading (100%)         
  - Installing fideloper/proxy (3.3.4): Downloading (100%)
        

[output truncated]

Generating optimized autoload files > @php -r “file_exists(‘.env’) || copy(‘.env.example’, ‘.env’);” > @php artisan key:generate Application key [base64:*******] set successfully. > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Package manifest generated successfully. Application ready! Build something amazing.

8. Fin

Voila:

laravel

When you try and browse to your project, you first hit the hosts file which returns the IP address. Your browser connects to this IP address, which is a virtual machine running on your machine, and Nginx is the one listening for connections. The request your browser makes is passed (by Nginx) to Laravel, which generates the page and sends it all back to your browser. Magic.

**Update: **You might notice in the screenshot above the URL is example.dev, this was how the tutorial was originally written, but Chrome now doesn’t allow this as .dev is a valid TLD, therefore all example.dev mentions in the post have been changed to .local

Wrap-up

Hopefully this tutorial covered everything you needed to get going with your own local Laravel development setup, but if there was anything missing or that doesn’t work for you, drop me an email or leave a comment below.

It doesn’t work!

If you can’t browse to your website after following the post, first check to ensure a .env file exists in your Laravel installation directory. You can run php artisan key:generate in case a key wasn’t generated at installation time. Finally, double check all file paths you have created vs. what you have configured in Homestead.yaml. Any changes to the yaml file will require you to run vagrant halt and vagrant up --provision from within the Homestead directory on your local machine.

Adding Additional Websites

In order to add a new website to your local dev environment, simply:

  1. Create a /etc/hosts entry for your domain
  2. Create your project (i.e. cd ~/code; laravel new myblog)
  3. Add a map (and database, if needed) to ~/Homestead/Homestead.yaml
  4. Run a vagrant halt followed by a vagrant up --provision

Sequel Pro

I highly recommend downloading Sequel Pro for connecting to your Homestead box’s MySQL server. It gives you a great GUI for interacting with the database and is free to use (funded by donations).

sequelpro

Advanced Topics

Homestead can have more advanced setups in terms of port-forwarding, software, services and more – if you want do anything extra with Homestead then be sure to check out the official documentation.