Laravel Valet

Development environment for Mac minimalists.

Nick DeNardis

 

Minimalist. UX crafter. Library Scientist. Speaker. Realist.

 

Web Director at Wayne State University.

 

Organizes TEDxDetroit, HighEdWeb regional conferences, Detroit Laravel & Refresh Detroit.

 

@nickdenardis

MAMP?
Vagrant?
Homestead?
Valet...

 

Sound Familiar?

MAMP installs a local server environment in a matter of seconds on your computer. It comes free of charge, and is easily installed. MAMP will not compromise any existing Apache installation already running on your system. You can install Apache, PHP and MySQL without starting a script or having to change any configuration files! Furthermore, if MAMP is no longer needed, just delete the MAMP folder and everything returns to its original state.

Vagrant

server_ip             = "10.10.10.11"
server_cpus           = "1"   # Cores
server_memory         = "1024" # MB
server_swap           = "2048" 
# Guideline: Between one or two times the server_memory

# Default web server document root
public_folder         = "/vagrant"
$ cat /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
10.10.10.11 myapp.dev
10.10.10.11 anotherapp.dev
10.10.10.11 testingapp.dev
10.10.10.11 trysomething.dev
10.10.10.11 lastapp.dev

Homestead

 
---
ip: "192.168.10.10"
memory: 2048
cpus: 1
provider: virtualbox
$ cat /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
10.10.10.11 myapp.dev
10.10.10.11 anotherapp.dev
10.10.10.11 testingapp.dev
10.10.10.11 trysomething.dev
10.10.10.11 lastapp.dev

192.168.10.10 myapp.app
192.168.10.10 anotherapp.app
192.168.10.10 testingapp.app
192.168.10.10 trysomething.app
192.168.10.10 lastapp.app

Valet

 
composer global require laravel/valet
valet install
$ scutil --dns

resolver #8
  domain   : dev
  nameserver[0] : 127.0.0.1
  flags    : Request A records, Request AAAA records
Reachable, Local Address, Directly Reachable Address

Valet is a Laravel development environment for Mac minimalists. No Vagrant, No Apache, No Nginx, No /etc/hosts file. You can even share your sites publicly using local tunnels. A blazing fast Laravel development environment that uses roughly 7mb of RAM.

Valet isn't a complete replacement for Vagrant or Homestead, but provides a great alternative if you want flexible basics, prefer extreme speed, or are working on a machine with a limited amount of RAM.

Installation

# Install Brew
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

# Ensure it is up to date
$ brew update

# Install PHP 7
$ brew install homebrew/php/php70

# Install Composer
$ brew install composer

# Ensure composer is in your path
$ which composer
$ export PATH="$PATH:vendor/bin:$HOME/.composer/vendor/bin"

# Install valet package
$ composer global require laravel/valet

# Ensure path and valet are reachable
$ which valet

# Run initial setup
$ valet install

# Ensure valet setup
$ valet

Local config directory

/Users/[username]/.valet
├── Caddy
├── Caddyfile
├── Certificates
├── Drivers
│   ├── SampleValetDriver.php
├── Extensions
├── Sites
├── config.json
└── dnsmasq.conf

6 directories, 5 files

Running, Stoping, Updating

# Check the most recent version
$ valet on-latest-version
YES

# Update to the most recent version
$ composer global update

# See the list of services running
$ brew services list
Name    Status  User         Plist
dnsmasq started root         /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
mariadb started nickdenardis /Users/nickdenardis/Library/LaunchAgents/homebrew.mxcl.mariadb.plist
php70   started root         /Library/LaunchDaemons/homebrew.mxcl.php70.plist

# Stop valet
$ valet stop
Valet services have been stopped.

# Only stops the PHP service
$ brew services list
Name    Status  User         Plist
dnsmasq started root         /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
mariadb started nickdenardis /Users/nickdenardis/Library/LaunchAgents/homebrew.mxcl.mariadb.plist
php70   stopped

# Start valet back up
$ valet start
Valet services have been started.

Brew services

 
# Stop other services
$ brew services stop mariadb
Stopping `mariadb`... (might take a while)
==> Successfully stopped `mariadb` (label: homebrew.mxcl.mariadb)

# Start/Restart
$ brew services start|stop|restart --all

Database

 
# Install MariaDB
$ brew install mariadb

########################################################################

To connect:
    mysql -uroot

To have launchd start mariadb now and restart at login:
  brew services start mariadb

########################################################################

# Change the root password
$ mysqladmin -u root password newpass

# Login to the database
$ mysql -uroot -p
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.1.14-MariaDB Homebrew

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

Additional PHP extensions

 
# Install mcrypt
$ brew install php70-mcrypt

To finish installing mcrypt for PHP 7.0:
  * /usr/local/etc/php/7.0/conf.d/ext-mcrypt.ini was created,
    do not forget to remove it upon extension removal.
  * Validate installation via one of the following methods:
  *
  * Using PHP from a webserver:
  * - Restart your webserver.
  * - Write a PHP page that calls "phpinfo();"
  * - Load it in a browser and look for the info on the mcrypt module.
  * - If you see it, you have been successful!
  *
  * Using PHP from the command line:
  * - Run `php -i "(command-line 'phpinfo()')"`
  * - Look for the info on the mcrypt module.
  * - If you see it, you have been successful!

Now what?

Testing our magic powers

Valet 1.1.12

$ valet
Laravel Valet version 1.1.12

Usage:
  command [options] [arguments]

Available commands:
  domain             Get or set the domain used for Valet sites
  fetch-share-url    Get the URL to the current Ngrok tunnel
  forget             Remove the current working directory from Valet's list of paths
  help               Displays help for a command
  install            Install the Valet services
  link               Link the current working directory to Valet
  links              Display all of the registered Valet links
  list               Lists commands
  logs               Stream all of the logs for all Laravel sites registered with Valet
  on-latest-version  Determine if this is the latest version of Valet
  open               Open the site for the current directory in your browser
  park               Register the current working directory with Valet
  paths              Get all of the paths registered with Valet
  restart            Restart the Valet services
  secure
  start              Start the Valet services
  stop               Stop the Valet services
  uninstall          Uninstall the Valet services
  unlink             Remove the specified Valet link
  unsecure
  which              Determine which Valet driver serves the current working directory

The parking lot

# Make a directory to host all valet sites
$ mkdir ~/Sites/valet/

# Park valet in this directory
$ cd ~/Sites/valet/
$ valet park

# View all parked directories
$ valet paths
[
    "/Users/nickdenardis/.valet/Sites",
    "/Users/nickdenardis/Sites/valet"
]

Serving an app

# Make sure you have the laravel installer available
$ which laravel
or
$ composer global require "laravel/installer"

# Move to the parked directory
$ cd ~/Sites/valet/

# New Laravel app
$ laravel new myapp

# Open the new app in a browser
$ cd myapp
$ valet open

Valet domain [tld]

# View the top level domain (TLD) configured
$ valet domain
dev

# Change the TLD to anything you want
$ valet domain nick
Your Valet domain has been updated to [nick].

# Check the resolvers
$ scutil --dns

...
resolver #8
  domain   : nick
  nameserver[0] : 127.0.0.1
  flags    : Request A records, Request AAAA records
Reachable, Local Address, Directly Reachable Address

# Check the IP a domain resolves to
$ dscacheutil -q host -a name myapp.nick

name: myapp.nick
ip_address: 127.0.0.1

Valet link

 
# Create a website outside of the 'parked' directory
$ cd ~/Desktop/uniqueapp/

# Link in this directory to Valet
$ valet link

# Check that it is part of the linked list
$ valet links

...
total 8
drwxr-xr-x  102 Jun  9 13:54 .
drwxr-xr-x  340 Jun  7 14:58 ..
lrwxr-xr-x   35 Jun  9 13:54 newness -> /Users/nickdenardis/Desktop/uniqueapp


# Website should be available at the [foldername].[tld]
$ open http://uniqueapp.dev/
or
$ valet open

Wordpress?

No problem.

Wordpress install

 
# Install the WP CLI tool
$ brew install wp-cli

# Make a directory 
$ mkdir ~/Sites/valet/blog && cd $_

# Download Wordpress
$ wp core download
Downloading WordPress 4.5.2 (en_US)...
md5 hash verified: 056da124260ed5b4465ec1fb2f9b7155
Success: WordPress downloaded.

# Setup the config
$ wp core config --dbname=blogs --dbuser=root --dbpass=password

# Setup the database
$ mysql -uroot -e "create database blog;"
$ mysql -uroot -e "GRANT ALL PRIVILEGES ON blog.* TO root@localhost IDENTIFIED BY 'root'"

# Install Wordpress
$ wp core install --url=blog.dev \
--title="My Blog" \
--admin_user=admin \
--admin_password=password \
--admin_email=user@email.com

Success: WordPress installed successfully.

# Visit the live website
$ valet open

Local SSL

 
# Navigate to the site directory
$ cd easyadmin

# Fetch a valid SSL
$ valet secure
The [easyadmin.dev] site has been secured with a fresh TLS certificate.

# Open the site in a browser
$ valet open

Sharing local developmet

 
# Navigate to the site directory
$ cd easyadmin

# Get a public URL
$ valet share

ngrok by @inconshreveable                                                                                         (Ctrl+C to quit)

Tunnel Status                 online
Version                       2.0.25/2.1.1
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://7721c692.ngrok.io -> easyadmin.dev:80
Forwarding                    https://7721c692.ngrok.io -> easyadmin.dev:80

Retrieve the sharable URL

 
# Navigate to the site directory
$ cd easyadmin

# Get a public URL
$ valet fetch-share-url
http://76ddf395.ngrok.io

Debugging locally

 
# View all valet site logs
$ valet logs

==> /Users/nickdenardis/.valet/Sites/newness/storage/logs/laravel.log <==

==> /Users/nickdenardis/Sites/valet/easyadmin/storage/logs/laravel.log <==

==> /Users/nickdenardis/Sites/valet/go/storage/logs/laravel.log <==

==> /Users/nickdenardis/Sites/valet/harvestwork/storage/logs/laravel.log <==

Custom Drivers

Into the unknown...

Our custom app

 
├── static
│   ├── child-sub-1.php
│   ├── child.php
│   ├── index.php
│   ├── news.php
│   ├── stubs.php
│   └── subsite
│       ├── child-sub-1.php
│       ├── child.php
│       └── index.php
└── www.80
    ├── 403.php
    ├── 404.php
    ├── 500.php
    ├── _resources
    │   ├── css
    │   │   ├── main.min.css
    │   │   └── main.min.css.map
    │   ├── fonts
    │   ├── images
    │   └── js
    │       ├── main.js
    │       └── main.js.map
    ├── _static -> /Users/nickdenardis/Sites/valet/newsite/static
    ├── favicon.ico
    └── robots.txt

Custom driver

class SampleValetDriver extends ValetDriver
{
    /**
     * Determine if the driver serves the request.
     */
    public function serves($sitePath, $siteName, $uri) {
        // if (file_exists($sitePath.'/file-that-identifies-my-framework')) {
        //     return true;
        // }

        return false;
    }

    /**
     * Determine if the incoming request is for a static file.
     */
    public function isStaticFile($sitePath, $siteName, $uri) {
        if (file_exists($staticFilePath = $sitePath.'/public/'.$uri)) {
            return $staticFilePath;
        }

        return false;
    }

    /**
     * Get the fully resolved path to the application's front controller.
     */
    public function frontControllerPath($sitePath, $siteName, $uri) {
        return $sitePath.'/public/index.php';
    }
}

Detecting our site

 
/**
 * Determine if the driver serves the request.
 *
 * @param  string  $sitePath
 * @param  string  $siteName
 * @param  string  $uri
 * @return bool
 */
public function serves($sitePath, $siteName, $uri)
{
    if (is_dir($sitePath.'/www.80')) {
        return true;
    }

    return false;
}

Serving static files

 
/**
 * Determine if the incoming request is for a static file.
 *
 * @param  string  $sitePath
 * @param  string  $siteName
 * @param  string  $uri
 * @return string|false
 */
public function isStaticFile($sitePath, $siteName, $uri)
{
    if (file_exists($staticFilePath = $sitePath.'/www.80'.$uri)) {
        return $staticFilePath;
    }

    if (file_exists($staticFilePath = $sitePath.'/static'.$uri)) {
        return $staticFilePath;
    }

    return false;
}

Serving the 'front controller"

 
/**
 * Get the fully resolved path to the application's front controller.
 *
 * @param  string  $sitePath
 * @param  string  $siteName
 * @param  string  $uri
 * @return string
 */
public function frontControllerPath($sitePath, $siteName, $uri)
{
    $uri = ($uri == '/')?'index.php':$uri;

    if (file_exists($staticFilePath = $sitePath.'/static'.$uri)) {
        return $staticFilePath;
    }

    return $sitePath.'/static/index.php';
}

Other useful functions

 
/**
 * Mutate the incoming URI.
 *
 * @param  string  $uri
 * @return string
 */
public function mutateUri($uri)
{
    return rtrim('/public_html'.$uri, '/');
}

Result

Thank you

@nickdenardis

Laravel Valet - Development environment for Mac minimalists.

By Nick DeNardis

Laravel Valet - Development environment for Mac minimalists.

Sometimes Homestead or a Vagrant environment is overkill to start up and play with a new project. We'll start fresh and build up a local development environment using Laravel Valet. With an overhead of roughly 7 megs of RAM, this is a lightweight alternative to begin a new project or small utility while saving battery and processor. http://www.meetup.com/Laravel-Detroit/events/231240777/

  • 1,841