I wanted to have a document and screencast to reference for the quickest way to get a new project up and running. And because I rarely make changes to my development environment setup and when something goes a bit wrong and I end up spending way too much time fumbling around to fix it, I wanted to better understand the Laravel Homestead and Laravel Valet environments to avoid future head-scratching when something doesn't work as expected.
This is my effort to document that understanding and provide a clean and rapid approach for setting up Laravel projects in Homestead and Valet -- and even Wordpress projects in Valet. The accompanying screencast demonstrates just how quickly they can be set up when these tools are incoporated into your workflow. -- Ryan
WP-CLI -- Laravel Valet also works for Wordpress sites. The tutorial covers its setup too.
Laracasts:
Laravel 5 Fundamentals: Virtual Machines and Homestead
Thanks to Taylor Otwell, Adam Wathan and Jeffrey Way for these excellent tools and instructions on how to use them.
Using a Mac, Oh My Zsh and familiarity with Laravel, the command-line interface, MySQL from the command-line, Composer and Homebrew.
Versions implemented:
- Homestead: 3.0.2
- Laravel: 5.3 dev
- Vagrant: 1.8.4 -- running Ubuntu 16.04
- Valet: 1.1.12
- Virtual Box: 5.0.24
In my haste to learn to code and build projects quickly, I've tended to lack some basic knowledge about some basic things. Here's what I've come to better understand about the ~
directory contents as they relate to the development environment:
// "~" (folders and files referenced in this block are within the `~` or `home` directory)
|-- Code // where I store all of my Laravel project code per Jeffrey Way's standard practice
|-- .composer // heavily used by Laravel; assumption is you are already using [Composer](https://getcomposer.org/) and have this directory in place
|-- vendor
|-- bin // path to the executables (actually, symbolic links in the case of Laravel) that the framework makes use of
|-- laravel // should already exist if you have Laravel installed
|-- valet // will be created upon installing Valet
|-- Documents // this directory is being referenced to note that our main development directories are also found within the same `~` directory as many common Mac folders such as Documents, Desktop and Applications
|-- .homestead
|-- Homestead.yaml // manages our sites' paths and domains as well as syncs to our main Code directory to the Homestead virtual machine's Code directory
|-- Homestead // main application directory from the Homestead install
|-- Vagrant // main application directory from the Vagrant install
|-- VirtualBox VMs // main application directory from the VirtualBox install and where the running machine contents will be stored
|-- .valet // main application directory from the Valet install
|-- .zshrc // zsh bash script file and contains the `PATH` environment variable reference we'll be updating to run our applications' executables
// "/" (folders and files referenced in this block are within the `/` or `root` directory)
|-- etc/hosts // already on the Mac by default and to be used by the Homestead virtual machine for setting our project domains to the Homestead IP address
|-- usr
|-- local
|-- bin
|-- wp // path to wp-cli executable and links to many other system executables
|-- etc
|-- php
|-- 7.0
|-- php.ini // php.ini file being referenced by Valet
Note: VirtualBox and Vagrant also have folders in the
/opt
directory as many standard Mac applications also do.
That's more or less the scope of the directories and files our development environment applications will make use of.
If you're able to call the Laravel installer from any directory by keying laravel
into the command-line, then you've most likely done one of the following in your bash scripts (assuming you're using ~/.zshrc
or possibly .bash_profile
if not):
a) Aliased the path to the executable:
alias laravel="~/.composer/vendor/bin/laravel"
Note: As shown in the
~ Directory Structure
section above,~/.composer/vendor/bin/laravel
is where Laravel places the link to the installer executable by default.
b) Updated your PATH
environment variable:
export PATH="/Users/ryandobbs/.composer/vendor/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
// or
export PATH=~/.composer/vendor/bin:$PATH
The PATH environment variable is a variable intended to give the root user access to certain administrative commands including commands provided by these development environment applications.
As we've seen, we can add to the PATH variable to include new commands like these and even bypass PATH by aliasing the commands directly to their respective executables.
Note: If you've done something like (b), then you shouldn't have any issues running Valet once installed because Laravel also places its executable link in the same
bin
directory.
For any changes you're making to the
PATH
environment variable, be sure to open a new terminal window to see those changes reflected.
Note: Assumes both Virtual Box and Vagrant are currently installed. Installation is quite simple and once installed, you will see their directories in the
~
directory as referenced earlier.
To add the Homestead Vagrant box, the Laravel Homestead installation documentation has us run:
$ vagrant box add laravel/homestead
Note: I ran the command from the
~
directory, but this is not important sincevagrant
should be accessible from anywhere and place the homestead box within its~/.vagrant.d
directory regardless.
When successfully installed, the output should be something like:
==> box: Successfully added box 'laravel/homestead' (v0.5.0) for 'virtualbox'!
Next, we'll install Homestead from the GitHub repository. If not already there, make sure to cd
into the ~
directory, and run the following:
$ git clone https://github.com/laravel/homestead.git Homestead
And then run:
$ bash init.sh
The command above sets up the ~/.homestead
directory and creates the Homestead.yaml
configuration file we'll update next for our new project sites. When you open the Homestead.yaml
file you'll see:
// ~/.homestead/Homestead.yaml
ip: "192.168.10.10" // ip used by homestead
memory: 2048
cpus: 1
provider: virtualbox // defaults to virtualbox
authorize: ~/.ssh/id_rsa.pub // allows us to ssh into virtual machine;
// if you haven't yet generated your public and private ssh keys, see note below
keys:
- ~/.ssh/id_rsa // same as comment above
folders:
- map: ~/Code // directory for my Laravel projects...
to: /home/vagrant/Code // being mapped to vm
sites:
- map: homestead.app // default initial domain
to: /home/vagrant/Code/Laravel/public // default initial path to project
// note: we're adding this now for our new project
- map: homestead-project.app // new domain
to: /home/vagrant/Code/homestead-project/public // new path
databases:
- homestead
Above, we've added to sites
the new project we'll be creating with the homestead-project.app
domain and homestead-project/public
project path for setting up our tutorial example. A database named homestead
will also be created when first initiaizing the virtual machine.
Other project references and databases can be added here later on and then by calling a reprovision
command that will be shown below.
Note: If you haven't yet been required to generate the private and public ssh keys for you computer, just search
mac generate ssh key
. Two articles that come up at the time of this writing are one from github and the other by joyent. Once done, just be sure that the paths referenced inHomestead.yaml
forauthorize
andkeys
are correct for yours.
Let's go into our hosts
file and associate the homestead
ip address with the new domain homestead-project.app
. You should see something like the following:
// /etc/hosts
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
And to it we'll add:
192.168.10.10 homestead-project.app
From our Code
directory, we'll pull in an fresh Laravel project giving it the name of homestead-project
as we indicated in the sites
path of the Homestead.yaml
file so that we can test those defaults. Within the Code
directory we'll run the following:
$ laravel new homestead-project
We should now see the new Laravel project homestead-project
in this Code
directory.
Note and a warning: If you run this command outside of the virtual machine as we're doing here, be sure to have installed an up to date version of PHP. (This can be done easily through Homebrew.)
This becomes an issue when the local machine version of PHP does not meet the minimum requirements of the project dependencies to be installed. I've had more than a head-scratching moment trying to figure out why I couldn't get a development version of Laravel to install. So keep it up to date or always run this command from within a current Homestead virtual machine.
To be able to install a project from within our virtual machine, we'll be able to
ssh
into it by runninghomestead ssh
once our setup is complete and the machine is running. Because theCode
directories are synced, as was establshed in theHomestead.yaml
file, we can then execute thelaravel new homestead-project
command in the same way from there.
Next, we run vagrant up
from within the ~/Homestead
directory to boot up the Homestead box (or virtual machine):
// ~/Homestead
$ vagrant up
From the browser, we should be able to go to homestead.app
and see the Laravel 5
default landing page text.
Note: this also created our
homestead
database. We'll test our project connection to this database shortly.
And that's it. We've successfully set up our Homestead
development environment, created our first example project and loaded its welcome page in the browser.
If we want to be able to reference the Homestead virtual machine from anywhere and not have to cd into the Homestead directory itself, we can add the following to our .zshrc
file:
function homestead() {
( cd ~/Homestead && vagrant $* )
}
Note: This is different from the aliasing or updating of the
PATH
environment variable from earlier because here we're calling onhomestead
as a function, which mimics cd-ing into the Homestead directory and from there executingvagrant
commands.
Once in place, we can call such vagrant
methods on the Homestead box in the following manner:
$ homestead up // to initialize the machine
$ homestead provision // to reset machine after adding a new project, for example
$ homestead ssh // to ssh into the virtual machine
$ homestead halt // to halt the running of the vm
Note: Again, be sure you've opened a new terminal window in order for these commands to take effect after adding the
homestead()
function to the.zshrc
file.
Having run vagrant up
earlier or by running homestead up
now, we also have an active instance of mysql
within the homestead
virtual machine and therefore, the ability to access our homestead
database. Let's ssh
in:
$ homestead ssh
Then cd
into the homestead-project
directory and run the default migration that comes with Laravel out of the box and includes a users
table and then log in to mysql
:
// ~/Code/homestead-project
$ php artisan migrate
$ mysql -u homestead -p // secret
Note:
Username
,password
anddatabase
referenced above and below are also set within the.env
file of our project.
Once in, we'll seek out the newly migrated tables:
mysql> show databases;
mysql> use homestead;
mysql> show tables;
We should see the tables migrations
, users
and ...
indicating that we were able to successfully run the default migration as well.
The Valet documentation is excellent and concise, but here's the gist:
Update brew:
$ brew update
Note: Assumes you already have Homebrew set up on your system.
We'll then update our local system to run PHP 7.0:
$ brew install homebrew/php/php70
Note: This is the method I was referencing earlier as a way to keep the local PHP version as current as new Homestead boxes, thus allowing you to install new projects to the
Code
directory without having to do so from within the virtual machine.
We'll bring in Valet through Composer:
$ composer global require laravel/valet
And then install Valet:
$ valet install
Then from the Code
directory, we'll run:
$ valet park
This will now serve any Laravel project within the Code
directory by simply adding .dev
to the end of the project directory name in the browser.
Note: You should have access to the
valet
command. If runningvalet install
returns "command not found", you'll want to use one of the methods discussed earlier of either aliasing or adding to yourPATH
~/.composer/vendor/bin
(or/Users/yourcomputername/.composer/vendor/bin
) which is also the path where thevalet
executable is placed by Laravel by default.
Let's make sure we're in our Code
directory and pull in a new project:
$ laravel new valet-project
We can now go to the browser, type in valet-project.dev
and see the Laravel 5
welcome page text. Simple as that.
If not already installed on your local machine, we'll import mysql
or mariadb
through brew
.
$ brew install mysql
// or
$ brew install mariadb
Note: It doesn't matter which directory you're in. Brew will install them globally.
Either install is fine. Both use the same command to fire up the local mysql server:
mysql.server start
And if you see the Success!
message, you should be up and running with your local mysql server.
If you receive
ERROR! The server quit without updating PID file (/usr/local/var/mysql/xxxxxx.local.pid)
, run the following:
$ sudo chown -R $(whoami):admin /user/local
This command will give the logged-in user permission to update the
xxxxxx.local.pid
file. Rerun themysql.server start
command, and it should now returnSUCCESS!
Similar to what we did for the homestead-project
database setup, we'll now do for the valet-project
setup from our local mysql
server. First we log in:
$ mysql -uroot -p
We create the database manually:
mysql> create database valet;
mysql> exit
We should now have a new valet
database.
Next, let's update the laravel-project
.env
file in the text editor setting the database related variables as follows:
// ~/Code/valet-project/.env
DB_DATABASE=valet
DB_USERNAME=root
DB_PASSWORD=
We'll close out and test that our valet-project
is capable of updating the database. The project directory gives us access to the project specific artisan
commands:
// ~/Code/valet-project
$ php artisan migrate
$ mysql -u root -p // no password
Once in, we'll seek out the newly migrated tables:
mysql> show databases;
mysql> use valet;
mysql> show tables;
We should see the tables migrations
, users
and ...
indicating that we were able to successfully run the default migration for our valet project as well.
The Wordpress command-line interface documentation is also very well done, but again, here's the gist:
We begin by installing WP-CLI from within the ~
directory as follows:
$ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
We make the file executable:
$ chmod +x wp-cli.phar
And move it where our PATH
environment variable will have access to it. I'm putting it within /usr/local/bin
:
$ mv wp-cli.phar /usr/local/bin/wp
You should now have access to wp
as a command. We'll make use of the command and it's many methods to install a basic site next.
First we create the new project directory within the Code
directory:
$ mkdir wordpress-project
Note: Since the
Code
is where we'vepark
ed the Valet, the project name should be the URL and because Wordpress also uses an index.php file from within the project directory as it's entry point, Valet will be able to serve the WP site through the same mechanisms it uses to serve Laravel sites.)
We cd
into the new directory and run:
$ wp core download
Next, we create a worpress user for mysql
who will be able to access the database:
$ mysql -u root -p
mysql> create user 'wordpress'@'localhost' identified by 'secret';
mysql> grant all privileges on wordpress.* to 'wordpress'@'localhost' with grant option;
mysql> exit
Then we run wp core config
with a few options to generate the basic wp-config.php
file:
$ wp core config --dbname=wordpress --dbuser=wordpress --dbpass=secret --dbhost=127.0.0.1
With the config file in place, we're able to create the database:
$ wp db create
Note: The local MySQL database system must be running for this to work.
Finally, we run wp core install
with a few options as well:
$ wp core install --url=wordpress-project.dev --title="Workpress Project" --admin_user=Ryan --admin_password=secret [email protected]
If we head over to the browser and enter wordpress-project.dev
and wordpress-project.dev/wp-admin
, we should see a basic wordpress site up and running and have access to the admin backend. From here, it's a matter of of using the cli and wordpress GUI to install templates as you normally would.
Note: If you run into upload and timeout errors when working with your wordpress templates, the errors will most likely be referring to settings in the
php.ini
file. Because we're using Valet and the PHP7 for our local server, changes will be made to thephp.ini
file located at/usr/local/etc/php/7.0/php.ini
.
To see the database tables generated by the install
command:
$ mysql -u wordpress -p // secret
mysql> show databases;
mysql> use wordpress;
mysql> show tables;
The ~
and /
directory/folder structure and PATH
environment variable have taken time for me to grasp. The exercise of writing this tutorial and creating the screencast has been very helpful. I would recommend working through such an exercise if for no other reason. But a nice perk is to now be able to create new projects on the fly and get coding very quickly -- and now do so with knowledge of where things are and what's actually going on. This effort has definitely served its purpose.
Anyway, all for now. If you made it this far, I hope you found it helpful. And hopefully, you were able to produce the same results along the way. If not, definitely explore the references mentioned. If you have questions or comments, feel free to reach out to me on twitter -- @dobbsryan
. -- Ryan