Skip to content

Instantly share code, notes, and snippets.

@dobbsryan
Last active July 15, 2016 23:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dobbsryan/f983aaf6ba9d3f92d4cb790fb657c760 to your computer and use it in GitHub Desktop.
Save dobbsryan/f983aaf6ba9d3f92d4cb790fb657c760 to your computer and use it in GitHub Desktop.

Laravel Homestead and Valet Quick Project Setup

Motivation

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

Reference Documentation

Laravel Homestead

Laravel Valet

VirtualBox Download

Vagrant Download

WP-CLI -- Laravel Valet also works for Wordpress sites. The tutorial covers its setup too.

Reference Videos

Laracasts:

Laravel 5 Fundamentals: Virtual Machines and Homestead

Laravel Valet is the Bomb

Thanks

Thanks to Taylor Otwell, Adam Wathan and Jeffrey Way for these excellent tools and instructions on how to use them.

Assumptions

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

1) Brief Overview of Relevant ~ (Home) and / (Root) Directory Contents and Calling of Executables

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:

~ Directory Structure

// "~" (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

/ Directory Structure

// "/" (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.

Calling Executables from the Command-line

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.

2) Setting Up Laravel Homestead from Scratch

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 since vagrant 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 in Homestead.yaml for authorize and keys 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

New homestead-project Project Install

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 running homestead ssh once our setup is complete and the machine is running. Because the Code directories are synced, as was establshed in the Homestead.yaml file, we can then execute the laravel 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.

Referencing the Homestead Virtual Machine from Anywhere

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 on homestead as a function, which mimics cd-ing into the Homestead directory and from there executing vagrant 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.

Homestead Database Connection

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 and database 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.

3) Setting Up Laravel Valet from Scratch

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 running valet install returns "command not found", you'll want to use one of the methods discussed earlier of either aliasing or adding to your PATH ~/.composer/vendor/bin (or /Users/yourcomputername/.composer/vendor/bin) which is also the path where the valet executable is placed by Laravel by default.

New valet-project Project Install

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.

Valet Database Connection

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 the mysql.server start command, and it should now return SUCCESS!

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.

4) Setting Up WP-CLI and a Wordpress Site from Scratch

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.

New wordpress-project Project Install

First we create the new project directory within the Code directory:

$ mkdir wordpress-project

Note: Since the Code is where we've parked 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 --admin_email=ryan@ryandobbs.com

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 the php.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;

6) Conclusion

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment