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 ValetNote: VirtualBox and Vagrant also have folders in the
/optdirectory 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 Structuresection above,~/.composer/vendor/bin/laravelis 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:$PATHThe 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
bindirectory.
For any changes you're making to the
PATHenvironment 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 sincevagrantshould be accessible from anywhere and place the homestead box within its~/.vagrant.ddirectory 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:
- homesteadAbove, 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.yamlforauthorizeandkeysare 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 localhostAnd to it we'll add:
192.168.10.10 homestead-project.appFrom 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-projectWe 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
sshinto it by runninghomestead sshonce our setup is complete and the machine is running. Because theCodedirectories are synced, as was establshed in theHomestead.yamlfile, we can then execute thelaravel new homestead-projectcommand 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 upFrom 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
homesteaddatabase. 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
PATHenvironment variable from earlier because here we're calling onhomesteadas a function, which mimics cd-ing into the Homestead directory and from there executingvagrantcommands.
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 vmNote: 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.zshrcfile.
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 sshThen 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 // secretNote:
Username,passwordanddatabasereferenced above and below are also set within the.envfile 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 updateNote: 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/php70Note: 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
Codedirectory without having to do so from within the virtual machine.
We'll bring in Valet through Composer:
$ composer global require laravel/valetAnd then install Valet:
$ valet installThen from the Code directory, we'll run:
$ valet parkThis 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
valetcommand. If runningvalet installreturns "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 thevaletexecutable 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-projectWe 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 mariadbNote: 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 startAnd 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/localThis command will give the logged-in user permission to update the
xxxxxx.local.pidfile. Rerun themysql.server startcommand, 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 -pWe create the database manually:
mysql> create database valet;
mysql> exitWe 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 passwordOnce 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.pharWe make the file executable:
$ chmod +x wp-cli.pharAnd 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/wpYou 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-projectNote: Since the
Codeis where we'veparked 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 downloadNext, 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> exitThen 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.1With the config file in place, we're able to create the database:
$ wp db createNote: 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.inifile. Because we're using Valet and the PHP7 for our local server, changes will be made to thephp.inifile 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