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.
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$
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:
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.dev 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
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.dev to: /home/vagrant/code/example/public
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
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
example folder 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.dev, 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.dev
6. Composer Setup
At this point, we're almost good to go. All we need to do is create our Laravel project files! If you haven't got Composer yet, you'll need to install that first (if you've already got it, skip ahead) on your local machine - or you can use the version of Composer that's inside Homestead.
I have Composer installed on my host machine for a number of reasons, but if you don't have it installed, it's easiest to just use the copy that's inside your new virtual machine. To do that, simply
vagrant up followed by
vagrant ssh, and interact with Composer inside your virtual machine. Using the Homestead bundled version of Composer is often a safer bet as version mismatches are less likely to crop up.
We'll add the Laravel installer package to my local machine's version of Composer in my case:
Dev-Mac-Mini:~ dev$ sudo composer global require "laravel/installer" Password:
7. Create your Laravel project
Now we'll create that
~/code directory we discussed earlier, and add our example project:
Dev-Mac-Mini:~ dev$ cd ~; mkdir code; cd code Dev-Mac-Mini:code dev$ laravel new example.dev 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. Boot + Fin
Once you've generated your application files (or downloaded/imported your project), you should now be able to boot your Vagrant box (which lives in the Homestead directory) and browse to your site.
Dev-Mac-Mini:code dev$ cd ~/Homstead; vagrant up Bringing machine 'homestead-7' up with 'virtualbox' provider... ==> homestead-7: Checking if box 'laravel/homestead' is up to date... ==> homestead-7: Clearing any previously set forwarded ports... ==> homestead-7: Clearing any previously set network interfaces... ==> homestead-7: Preparing network interfaces based on configuration... homestead-7: Adapter 1: nat homestead-7: Adapter 2: hostonly ==> homestead-7: Forwarding ports... homestead-7: 80 (guest) => 8000 (host) (adapter 1) homestead-7: 443 (guest) => 44300 (host) (adapter 1) homestead-7: 3306 (guest) => 33060 (host) (adapter 1) homestead-7: 5432 (guest) => 54320 (host) (adapter 1) homestead-7: 8025 (guest) => 8025 (host) (adapter 1) homestead-7: 27017 (guest) => 27017 (host) (adapter 1) homestead-7: 22 (guest) => 2222 (host) (adapter 1) ==> homestead-7: Running 'pre-boot' VM customizations... ==> homestead-7: Booting VM... ==> homestead-7: Waiting for machine to boot. This may take a few minutes... homestead-7: SSH address: 127.0.0.1:2222 homestead-7: SSH username: vagrant homestead-7: SSH auth method: private key ==> homestead-7: Machine booted and ready! ==> homestead-7: Checking for guest additions in VM... ==> homestead-7: Setting hostname... ==> homestead-7: Configuring and enabling network interfaces... ==> homestead-7: Mounting shared folders... homestead-7: /vagrant => /Users/dev/Homestead homestead-7: /home/vagrant/code => /Users/dev/code ==> homestead-7: Running provisioner: file... ==> homestead-7: Running provisioner: shell... homestead-7: Running: inline script ==> homestead-7: Running provisioner: shell... homestead-7: Running: inline script ==> homestead-7: Running provisioner: shell... homestead-7: Running: inline script ==> homestead-7: Running provisioner: shell... homestead-7: Running: /var/folders/6l/nplc6qrd1qg2ngvppqqmtm8c0000gp/T/vagrant-shell20170928-1272-zn6lhp.sh ==> homestead-7: Running provisioner: shell... homestead-7: Running: script: Creating Certificate: example.dev ==> homestead-7: Running provisioner: shell... homestead-7: Running: script: Creating Site: example.dev ==> homestead-7: Running provisioner: shell... homestead-7: Running: script: Checking for old Schedule ==> homestead-7: Running provisioner: shell... homestead-7: Running: script: Restarting Nginx ==> homestead-7: Running provisioner: shell... homestead-7: Running: script: Creating MySQL Database: example ==> homestead-7: Running provisioner: shell... homestead-7: Running: script: Creating Postgres Database: example ==> homestead-7: Running provisioner: shell... homestead-7: Running: script: Clear Variables ==> homestead-7: Running provisioner: shell... homestead-7: Running: script: Update Composer ==> homestead-7: You are already using composer version 1.5.2 (stable channel). ==> homestead-7: Running provisioner: shell... homestead-7: Running: /var/folders/6l/nplc6qrd1qg2ngvppqqmtm8c0000gp/T/vagrant-shell20170928-1272-184vox8.sh Dev-Mac-Mini:Homestead dev$
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.
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.
Adding Additional Websites
In order to add a new website to your local dev environment, simply:
- Create a
/etc/hostsentry for your domain
- Create your project (i.e.
cd ~/code; laravel new myblog)
- Add a map (and database, if needed) to
- Run a
vagrant haltfollowed by a
vagrant up --provision
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).
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.