轻量级开发环境:Valet
简介
Valet 是为 Mac 打造的极简 Laravel 开发环境,没有 Vagrant,没有虚拟机,也无需配置 /etc/hosts
文件,还可以使用本地隧道公开分享你的站点。
启动 Mac 后,Laravel Valet 会在后台静默运行 Nginx,然后通过 DnsMasq,Valet 会代理所有针对 *.test
域名的请求指向本地安装的站点目录。
此外,这样一个极速的 Laravel 开发环境只需要占用 7M 内存。Valet 并不是想要替代 Vagrant 或者 Homestead,只是提供了另外一种选择,更加灵活、极速、以及占用更小的内存空间。正是基于这些原因,我们将 Valet 称之为轻量级的开发环境。
Valet 开箱支持但不限于以下软件和工具:
- Laravel
- Lumen
- Bedrock
- CakePHP 3
- Concrete5
- Contao
- Craft
- Drupal
- Jigsaw
- Joomla
- Katana
- Kirby
- Magento
- OctoberCMS
- Sculpin
- Slim
- Statamic
- Static HTML
- Symfony
- WordPress
- Zend
以上支持的驱动文件位于 ~/.composer/vendor/laravel/valet/cli/drivers
目录下,当然,你还可以通过自定义驱动扩展 Valet,自定义的驱动文件存放在 ~/.valet/Drivers
目录。
Valet 还是 Homestead
正如我们上篇文档所介绍的,Laravel 还提供了另外一个开发环境 Homestead。Homestead 和 Valet 的不同之处在于两者的目标受众和本地开发方式。
Homestead 提供了一个完整的、包含自动化 Nginx 配置的 Ubuntu 虚拟机,如果你需要一个完整的虚拟化 Linux 开发环境或者使用的是 Windows/Linux 操作系统,那么 Homestead 无疑是最佳选择,此外,学院君以为如果是公司团队进行正规的工程化开发,还是使用 Homestead 为佳,原因我在上篇文档中已经提及。
Valet 官方默认只支持 Mac,并且要求本地自行安装 PHP 和数据库服务器,当然这可以通过 Homebrew 命令轻松实现(brew install php
以及 brew install mysql
),Valet 通过最小的资源消耗提供了一个极速的本地开发环境,如果你只需要 PHP/MySQL 并且不需要完整的虚拟化开发环境,那么 Valet 将是最好的选择,学院君建议如果是 Mac 环境本地尝鲜,所以尝鲜就是以学习为目的或者只是快速做个 Demo 原型,那 Valet 无疑是很棒的选择。
最后,建议归建议,Valet 和 Homestead 都是搭建本地 Laravel 开发环境的好工具,最终选择使用哪一个取决于你个人的喜好或团队的需求。
安装
注:已安装的直接跳到升级部分。
Valet 要求 MacOS 操作系统并且已安装 Homebrew。安装之前,还要确保没有其他程序如Apache 或 Nginx 绑定到本地的 80 端口。安装步骤如下:
- 使用
brew update
安装或更新 Homebrew 到最新版本; - 通过 Homebrew 安装 PHP 7.4:
brew install php
; - 安装 Composer;
- 通过 Composer 安装 Valet:
composer global require laravel/valet
(确保~/.composer/vendor/bin
目录在系统路径中); - 运行
valet install
命令,这将会配置并安装 Valet 和 DnsMasq,然后注册 Valet 后台随机启动。
安装完 Valet 后,尝试使用命令如 ping foobar.test
在终端 ping 一下任意 *.test
域名,如果 Valet 安装正确就会看到来自 127.0.0.1
的响应:
每次系统启动的时候 Valet 会在后台自动启动,不需要再次手动运行 valet start
或 valet install
。
使用其他域名
默认情况下,Valet 使用 .test
域名后缀,如果你想要使用其他域名,可以使用 valet tld tld-name
命令。
例如,你想使用 .app
域名后缀取代 .test
,运行 valet tld app
,Valet 将会自动将站点域名后缀改为 *.app
。
数据库
注:已安装 MySQL 数据库忽略本条。
如果你需要数据库,可以在命令行通过 brew install mysql@5.7
安装MySQL,安装完成后就可以通过 brew services start mysql@5.7
来启动它,然后通过用户名 root
和一个空密码连接到本地数据库(主机是127.0.0.1
)。
PHP版本
Valet 允许你使用 valet use php@version
来切换 PHP 的版本,如果指定 PHP 版本不存在的话,Valet 会通过 Brew 自动帮你安装:
valet use php@7.2
valet use php // 默认PHP版本
注:Valet 一次只能使用一个 PHP 版本,即使你安装了多个 PHP 版本。
重置安装
如果你在安装运行 Valet 过程中遇到问题,可以在 valet install
之后执行 composer global update
命令重置安装以解决大部分问题,在极少数情况下,可能还需要通过执行 valet uninstall --force
来「硬重置」Valet 的安装。
升级
你可以在终端使用 composer global update
命令来升级 Valet。升级之后,最好运行下 valet install
命令以便 Valet 在必要情况下对配置文件进行升级。
升级到 Valet 2.0
注:先通过
valet --version
查看本机安装的 Valet 版本,如果版本已经大于 2.0 则可以跳过本段教程。
Valet 2.0 将 Valet 底层的 web 服务器从 Caddy 替换成了 Nginx,升级到这个版本之前需要运行以下命令来停止和卸载已经在后台运行的 Caddy:
valet stop
valet uninstall
接下来,需要升级到最新版本的 Valet。基于 Valet 的安装方式,你可以通过 Git 或 Composer 来实现,如果你是通过 Composer 安装的 Valet,需要通过如下方式更新到最新的主版本:
composer global require laravel/valet
最新的 Valet 源码下载好之后,运行 install
命令:
valet install
valet restart
升级之后,需要 re-park 和 re-link 站点。
访问站点
Valet 安装完成后,就可以启动服务站点,Valet 为此提供了两个命令:park
和 link
。
park
命令
- 在 Mac 系统中创建一个新目录,例如
mkdir ~/Sites
,然后进入这个目录并运行valet park
。这个命令会将当前所在目录作为 Web 根目录。 - 接下来,在新建的目录中创建一个新的 Laravel 站点:
laravel new blog
。 - 接下来,在浏览器中访问
http://blog.test
。
这就是我们要做的全部工作。现在,所有在 Sites
目录中创建的 Laravel 项目都可以通过 http://folder-name.test
这种方式在浏览器中访问,是不是很方便?
link
命令
link
命令也可以用于访问本地 Laravel 站点,当你想要提供单个访问站点时这个命令很有用。
- 要使用这个命令,先切换到你的某个项目并运行
valet link app-name
,这样 Valet 会在~/.config/valet/Sites
中创建一个符号链接指向当前工作目录。 - 运行完
link
命令后,可以在浏览器中通过http://app-name.test
访问站点。
要查看所有的链接目录,可以运行 valet links
命令。你也可以通过 valet unlink app-name
来删除符号链接。
注:你还可以使用
valet link
将多个(子)域名指向同一个应用,要添加子域名或其它域名到应用,可以在应用目录下运行valet link subdomain.app-name
。
一般来说我们使用 park
命令更方便一些,省去了后面新建应用重复执行命令,但是如果有子域名这类特殊需求,只能使用 link
命令来实现了。
通过 TLS 保护站点
默认情况下,Valet 使用 HTTP 协议,如果你想要使用 HTTP/2 通过加密的 TLS 为站点提供服务,可以使用 secure
命令。例如,如果你的站点域名是 laravel.test
,可以使用如下命令:
valet secure laravel
要想回到"非安全"的 HTTP,可以使用 unsecure
命令。和 secure
命令一样,该命令接收主机名作为参数:
valet unsecure laravel
分享站点
Valet 还提供了一个命令用于将本地站点分享给其他人,这不需要任何额外工具即可实现,和 Homestead 一样,底层也是通过 Ngrok 实现。
通过 Ngrok 分享站点
要分享站点,切换到站点所在目录并运行 valet share
,这会生成一个可以公开访问的 URL 并插入剪贴板,以便你直接复制到浏览器地址栏,就是这么简单:
你可以通过 http://8f3361ed.ngrok.io/
或 https://8f3361ed.ngrok.io
从任意联网机器访问站点(因为已经公开到互联网上):
要停止共享站点,使用 Control + C
快捷键结束该命令即可。
注:关于 Ngrok 的更多使用细节,请参考 Ngrok 官方文档。
在局域网内分享站点
Valet 默认会限制只接收来自内部 127.0.0.1
地址的网络流量,这样一来你的本地开发机器就不会承受来自外部互联网的安全风险。
如果你希望允许局域网内的其他设备通过你的机器 IP 地址访问对应的 Valet 站点(例如 192.168.1.10/app-name.test
),则需要手动编辑相应站点的 Nginx 虚拟主机配置来解除这个限制,这个限制由 listen
指令上配置的 127.0.0.1
实现,即默认只监听来自本地 127.0.0.1
的网络请求,我们只需要移除 listen
指令配置的 127.0.0.1:
前缀即可。
注:做过生产环境 Nginx 配置的同学应该知道,我们在生产环境的配置就是这么做的,所以才可以接收来自外部网络的请求。
如果你没有在项目中运行过 valet secure
,可以通过编辑 /usr/local/etc/nginx/valet/valet.conf
文件统一开启所有非 HTTPS 站点的网络访问权限。不过,如果某个站点是 HTTPS 的,则需要编辑对应站点的 ~/.config/valet/Nginx/app-name.test
配置文件(其中 app-name
指代对应的站点域名)。
更新过 Nginx 配置后,需要运行 valet restart
命令让上述配置修改生效。然后,其他人就可以通过在自己机器的 hosts
文件中配置 192.168.1.10 app-name.test
然后通过 app-name.test
来访问你的 Valet 站点了(192.168.1.10
是你的 IP 地址)。
站点指定环境变量
有些使用其他框架的应用可能依赖服务器环境变量,但并没有提供在应用内配置这些变量的途径,在 Valet 中,可以通过在项目根目下添加 .valet-env.php
文件来配置这些站点指定环境变量,这些变量会被添加到 $_SERVER
全局数组中:
<?php
// Set $_SERVER['key'] to "value" for the foo.test site...
return [
'foo' => [
'key' => 'value',
],
];
// Set $_SERVER['key'] to "value" for all sites...
return [
'*' => [
'key' => 'value',
],
];
自定义 Valet 驱动
你还可以编写自定义的 Valet 驱动为非 Valet 原生支持的 PHP 应用提供服务。安装完 Valet 时系统会创建一个 ~/.config/valet/Drivers
目录,该目录中有一个 SampleValetDriver.php
文件,这个文件中有一个演示如何编写自定义驱动的示例。编写一个驱动只需要实现三个方法:serves
、isStaticFile
和 frontControllerPath
。
这三个方法接收 $sitePath
、$siteName
和 $uri
值作为参数,其中 $sitePath
表示站点目录,如 ~/Sites/my-project
,$siteName
表示主域名部分,如 my-project
,而 $uri
则是输入的请求地址,如 /foo/bar
。
编写好自定义的 Valet 驱动后,将其放到 ~/.config/valet/Drivers
目录并遵循 FrameworkValetDriver.php
这种命名方式,举个例子,如果你是在为 WordPress 编写自定义的 Valet 驱动,对应的文件名称为 WordPressValetDriver.php
。
下面我们来具体讨论并演示自定义 Valet 驱动需要实现的三个方法。
serves
方法
如果自定义驱动需要继续处理输入请求,serves
方法会返回true
,否则该方法返回 false
。因此,在这个方法中应该判断给定的 $sitePath
是否包含你服务类型的项目。
例如,假设我们编写的是 WordPressValetDriver
,那么对应 serves
方法如下:
/**
* Determine if the driver serves the request.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return void
* @translator laravelacademy.org
*/
public function serves($sitePath, $siteName, $uri)
{
return is_dir($sitePath.'/wp-admin');
}
isStaticFile
方法
isStaticFile
方法会判断输入请求是否是静态文件,例如图片或样式文件,如果文件是静态的,该方法会返回磁盘上的完整路径,如果输入请求不是请求静态文件,则返回 false
:
/**
* 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.'/public/'.$uri)) {
return $staticFilePath;
}
return false;
}
注:
isStaticFile
方法只有在serves
方法返回true
并且请求 URI 不是/
的时候才会被调用。
frontControllerPath
方法
frontControllerPath
方法会返回前端控制器的完整路径,通常是 index.php
:
/**
* 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)
{
return $sitePath.'/public/index.php';
}
关于自定义 Valet 驱动可以参考学院君为 Flarum 论坛编写的扩展教程:在 Mac 开发环境 Laravel Valet 中配置运行 Flarum 论坛系统。
本地驱动
如果你想要为单应用程序定义一个自定义的 Valet 驱动,在应用根目录下创建一个 LocalValetDriver.php
文件,自定义驱动类可以继承自 ValetDriver
基类或者继承自已存在的应用指定驱动类如 LaravelValetDriver
:
class LocalValetDriver extends LaravelValetDriver
{
/**
* Determine if the driver serves the request.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return bool
*/
public function serves($sitePath, $siteName, $uri)
{
return true;
}
/**
* 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)
{
return $sitePath.'/public_html/index.php';
}
}
其他常用 Valet 命令
命令 | 描述 |
---|---|
valet forget |
从「parked」目录运行该命令以便从 parked 目录列表中移除该目录 |
valet logs |
查看 Valet 服务写入的日志列表 |
valet paths |
查看你的「parked」路径 |
valet restart |
重启 Valet |
valet start |
启动 Valet |
valet stop |
关闭 Valet |
valet trust |
为 Brew 和 Valet 添加 sudoers 文件,这样运行 Valet 命令就不会要求输入密码了 |
valet uninstall |
卸载 Valet |
更多 Valet 命令,可以通过运行 valet list
查看。
Valet 目录&文件
如果在使用 Valet 过程中遇到环境问题,可以通过查找下列目录和文件进行排查:
文件/路径 | 描述 |
---|---|
~/.config/valet/ |
包含所有 Valet 配置,修改之前最好维护一份这个目录的备份 |
~/.config/valet/dnsmasq.d/ |
包含 DNSMasq 配置 |
~/.config/valet/Drivers/ |
包含自定义 Valet 驱动 |
~/.config/valet/Extensions/ |
包含自定义 Valet 扩展/命令 |
~/.config/valet/Nginx/ |
包含所有 Valet 生成的 Nginx 站点配置,这些文件会在运行 install 、secure 、tld 命令时重建 |
~/.config/valet/Sites/ |
包含所有链接项目的软连接 |
~/.config/valet/config.json |
Valet 的主配置文件 |
~/.config/valet/valet.sock |
Valet Nginx 配置中使用到的 PHP-FPM 套接字,只有当 PHP 正确运行时才存在 |
~/.config/valet/Log/fpm-php.www.log |
包含 PHP 错误的用户日志 |
~/.config/valet/Log/nginx-error.log |
包含 Nginx 错误的用户日志 |
/usr/local/var/log/php-fpm.log |
包含 PHP-FPM 错误的系统日志 |
/usr/local/var/log/nginx |
包含 Nginx 访问和错误日志 |
/usr/local/etc/php/X.X/conf.d |
包含各种 PHP 配置设置的 *.ini 文件 |
/usr/local/etc/php/X.X/php-fpm.d/valet-fpm.conf |
PHP-FPM 进程池配置文件 |
~/.composer/vendor/laravel/valet/cli/stubs/secure.valet.con |
用于构建站点证书的默认 Nginx 配置 |
2 Comments
请问下大佬,我这边环境 valet 环境装好后要启动 valet 项目必须再配置 hosts 文件才能正常访问,这是什么问题呢? Restarting dnsmasq... Restarting php... Restarting nginx... Valet services have been restarted.
local/etc/dnsmasq.d took 23s ➜ valet -v Laravel Valet 2.9.0
是不是域名后缀不对呢 你是使用 valet 默认域名后缀访问的吗 而且项目目录也要在valet管理之下