Installing Laravel Valet on MacOS
January 1, 2021 by Areg Sarkissian
This post is part of the Get Started with Production Ready Laravel series of posts.
Prerequisites
Install Homebrew
Install PHP (should install php-fpm)
Install Composer
Add /usr/local/bin to your
system path
Valet will install dnsmasq
and nginx
using homebrew
Installing and configuring valet
To install Valet run the following commands:
composer global require laravel/valet
valet --version
valet install
valet trust
valet use php
valet start
Updating and re-intstalling Valet
valet stop
#run this only if you have issues with valet installing
#see notes below about possible side effects of this command
#valet uninstall --force
composer global update
valet --version
valet install
valet trust
valet use php
valet start
The valet start
command also starts the dnsmaq and nginx services
Note. It seems that the
valet uninstall
command removes the current php installation so PHP and possibly its extensions may need to be re-installed via homebrew and pecl again. Also seems like the valet uninstall effected my current nvm node setting where node and npm were not found. This was most likely due to the node path setting being modified during the valet uninstall. To resolve that I used the nvm usecommand to reset the node path.
Resetting valet to use a new php version
When we swich php versions, the php command point to the new php version. Just to be safe we may have to inform valet about this by doing the following:
valet stop
rm ~/.config/valet/valet.sock
#php now point to a different version of php
valet use php
valet start
Also repeat the same steps anytime you install a new PHP extension.
Check that the ~/.config/valet/valet.sock
file exists.
If you run into issues. Try running:
valet install
valet use php
valet restart
Uninstalling and removing valet
valet stop
valet uninstall --force
composer global remove laravel/valet
sudo rm -rf ~/.config/valet
rm /usr/local/bin/valet
Additionally can stop and uninstall the valet installed dnsmasq and nginx services
sudo brew services stop nginx
sudo brew services stop dnsmasq
brew uninstall dnsmasq
brew uninstall nginx
Issues with composer when running composer update
composer global update is run anytime run composer global remove or composer global require we can also directly run composer global update
In either case sometimes composer global update fails with version conflict warnings
If this happens when trying to install, update or remove valet you may have to delete your composer.lock file and the vendor directory in the composer home directory ~/.composer
Then manually remove the valet package from composer.json and run:
composer global require laravel/valet
If you are unable to install due to composer errors, you may need to delete the composer.json and reinstall all the installed global packages including Laravel valet.
See the composer post for handling version conflict error details
Starting, stoping and restarting valet
Starting stoping and restarting valet also starts stops and restarts the dnsmasq and nginx services
valet start
valet stop
valet restart
Serving sites with valet
linking all projects within a directory
cd ~/myprojects
valet park
linking a single project
cd ~/myspecialprojects/myapp
valet link
Each project will be served locally using the project name and .test domain
http://<project_name>.test
The site will also respond to any subdomain
http://<subdomain>.<project_name>.test
we can show the linked sites
valet links
Also if we check the file ~/.config/valet/config.json
we will see that ~/myspecialprojects
directory is added to the paths property.
We can also the tld (top level domain) property is set to test which allows serving using .test domain. We can change this and run restart valet
to serve using a different domain. (just make sure it does not conflict with a real domain since dnsmasq will redirect it to the local nginx server)
cat ~/.config/valet/config.json
{
"tld": "test",
"paths": ["/Users/aregsarkissian/zdev/laravel"]
}
Removing linked sites
We can remove individual sites within a parked directory by entering the project and using the unlink command:
cd ~/myprojects/myotherapp
valet unlink
To unlink all projects within a parked directory enter the directory and use the forget command
cd ~/myprojects
valet forget
Valet configuration files
When we run the valet install
command, valet creates the configuration directory ~/.config/valet/
Important configuration files and directories
The ~/.config/valet/config.json
file lists the directories that hosts the Laravel projects.
Here is a list of other notable configuration locations:
~/.config/valet/config.json
~/.config/valet/Sites/
~/.config/valet/dnsmasq.d/
~/.config/valet/Nginx/
/usr/local/etc/php/X.X/php-fpm.d/valet-fpm.conf
~/.config/valet/valet.sock
for a full list and descriptions see Laravel valet documentation
https://laravel.com/docs/8.x/valet
Valet executable
requiring valet globally installs the valet executable file at:
~/.composer/vendor/laravel/valet/valet
The installation also adds the symlinks:
~/.composer/vendor/bin/valet -> ~/.composer/vendor/laravel/valet/valet
Usually we add ~/.composer/vendor/bin
to our system $PATH
variable to be able globally run executables symlinks that composer sets up in ~/.composer/vendor/bin
.
However Valet installs a symlink in /usr/local/bin
that points to the symlink in ~/.composer/vendor/bin
.
/usr/local/bin/valet -> /Users/aregsarkissian/.composer/vendor/laravel/valet/valet
So as long as we have /usr/local/bin
in our system $PATH
we will be able to at least run the valet command globally.
To see the location of the valet executable:
which valet
Which points to the composer symlink in my case since the ~/.composer/vendor/bin
in my $PATH
proceeds the /usr/local/bin
in $PATH
.
/Users/aregsarkissian/.composer/vendor/bin/valet
How valet works
the valet install
command will use Homebrew to download and install Nginx and Dnsmasq servers and configure Valet to use them. Installing Nginx and Dnsmasq will add the nginx and dnsmasq services on your system and start them up.
run brew list
to see if nginx and dnsmaq are installed
we can manually install and start them if for some reason valet is unable to install them
brew install dnsmasq
brew install nginx
sudo brew services start dnsmasq
sudo brew services start nginx
Valet is configured by default to route any <project_name>.test
domain using dnsmasq DNS resolver to the local Nginx server.
Dnsmasq resolves .test domains to the localhost, which the Nginx server is configured to listen on, while allowing other domains to be resolved to their IP address on the web.
In its valet configuration file at ~/.config/valet/valet.conf
, Nginx uses the Laravel project_name
in the domain to pass to fastcgi_index /Users/aregsarkissian/.composer/vendor/laravel/valet/server.php
php file that uses the valet driver to serve the project by using php to execute the public/index.php file in the project, hence serving the project at that URL.
The snippet below from ~/.composer/vendor/laravel/valet/server.php
shows how the php process requires
the index.php
file which is referenced as the $frontControllerPath in the script to execute the code in index.php
:
$frontControllerPath = $valetDriver->frontControllerPath(
$valetSitePath, $siteName, $uri
);
chdir(dirname($frontControllerPath));
require $frontControllerPath;
Valet configures the project paths including the project name and the .test
domain in ~/.config/valet/config.json.
The valet.conf file
Below is the content of the ~/.config/valet/valet.conf
file
server {
listen 127.0.0.1:80 default_server;
root /;
charset utf-8;
client_max_body_size 128M;
location /41c270e4-5535-4daa-b23e-c269744c2f45/ {
internal;
alias /;
try_files $uri $uri/;
}
location / {
rewrite ^ "/Users/aregsarkissian/.composer/vendor/laravel/valet/server.php" last;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log "/Users/aregsarkissian/.config/valet/Log/nginx-error.log";
error_page 404 "/Users/aregsarkissian/.composer/vendor/laravel/valet/server.php";
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass "unix:/Users/aregsarkissian/.config/valet/valet.sock";
fastcgi_index "/Users/aregsarkissian/.composer/vendor/laravel/valet/server.php";
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME "/Users/aregsarkissian/.composer/vendor/laravel/valet/server.php";
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
}