基于 Laravel Valet 在 Mac 系统搭建轻量级本地集成开发环境


简介

Valet 是为 Mac 打造的极简 Laravel 开发环境,没有 Vagrant,没有虚拟机,也无需配置 /etc/hosts 文件,还可以使用本地隧道公开分享你的站点。

启动 Mac 后,Laravel Valet 会在后台静默运行 Nginx,然后通过 DnsMasq,Valet 会代理所有针对 *.test 域名的请求指向本地安装的站点目录。

此外,这样一个极速的 Laravel 开发环境只需要占用 7M 内存。Valet 并不是想要替代 Vagrant 或者 Homestead,只是提供了另外一种选择,更加灵活、极速、以及占用更小的内存空间。正是基于这些原因,我们将 Valet 称之为轻量级的开发环境。

Valet 开箱支持但不限于以下软件和工具:

以上支持的驱动文件位于 ~/.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 startvalet install

使用其他域名

默认情况下,Valet 使用 .test 域名后缀,如果你想要使用其他域名,可以使用 valet tld tld-name 命令。

例如,你想使用 .app 域名后缀取代 .test,运行 valet tld app,Valet 将会自动将站点域名后缀改为 *.app

数据库

注:已安装 MySQL 数据库忽略本条。

如果你需要数据库,可以在命令行通过 brew install mysql 安装MySQL,安装完成后就可以通过 brew services start mysql 来启动它,然后通过用户名 root 和一个空密码连接到本地数据库(主机是 127.0.0.1):

ping foobar.test

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 安装完成后,就可以启动服务站点,Valet 为此提供了两个命令:parklink

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 并插入剪贴板,以便你直接复制到浏览器地址栏,就是这么简单:

通过 Ngrok 分享站点

你可以通过 http://3e9d87d777f2.ngrok.iohttps://3e9d87d777f2.ngrok.io 从任意联网机器访问站点(因为已经公开到互联网上,这里我测试的是从另一台 Windows 电脑访问 Mac 系统中运行的站点):

通过 Ngrok 分享链接访问站点

要停止共享站点,使用 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 的同时运行另一个独立的 Docker 站点(当然,Valet 和 Docker 不能同时绑定到 80 端口)。

要解决这个问题,可以使用 Valet 提供的 proxy 命令生成一个代理,例如,你可以像下面这样将所有指向 http://elasticsearch.test 域名的流量代理到 http://127.0.0.1:9200

valet proxy elasticsearch http://127.0.0.1:9200

如果不想使用这个代理了,可以使用 unproxy 命令取消:

valet unproxy elasticsearch

你还可以使用 proxies 命令列举所有被代理的站点配置:

valet proxies

自定义 Valet 驱动

你可以编写自定义的 Valet 驱动为非 Valet 原生支持的 PHP 应用提供服务。安装完 Valet 时系统会创建一个 ~/.config/valet/Drivers 目录,该目录中有一个 SampleValetDriver.php 文件,这个文件中有一个演示如何编写自定义驱动的示例。编写一个驱动只需要实现三个方法:servesisStaticFilefrontControllerPath

这三个方法接收 $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 站点配置,这些文件会在运行 installsecuretld 命令时重建
~/.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 配置

实例教程


Vote Vote Cancel Collect Collect Cancel

<< 上一篇: 基于 Laravel Telescope 提供本地调试解决方案

>> 下一篇: 没有下一篇了