宝塔面板不支持子目录灰度部署,因默认PHP配置强制所有请求经主站index.php处理;需手动在Nginx配置中为子目录(如/v2/)添加独立location块,指定alias、try_files及关键fastcgi_param SCRIPT_FILENAME $request_filename,否则仍运行主站代码。
为什么直接用 Nginx 子目录做灰度在宝塔里容易失败
因为宝塔默认的 PHP 项目站点配置会强制将所有请求通过
入口统一处理,而子目录(比如
)若没单独配置
和
,PHP 实际运行的仍是主站代码,根本不会加载新版本文件。
常见错误现象:
返回的是主站
的响应,或直接 500(找不到
对应的物理路径)。
关键点在于:子目录不是简单加个 location 就行,它需要独立的 PHP 上下文环境。
在宝塔中为子目录配置独立 PHP 运行环境
必须手动修改站点配置,不能只靠宝塔界面“子目录绑定”功能(该功能仅适用于静态或完全隔离的二级站点,不适用同项目多版本灰度)。
立即学习
“
PHP免费学习笔记(深入)
”;
进入宝塔 → 网站 → 对应站点 → 配置文件
在
块内添加如下
块(以
为例):
}
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
重点说明:
后路径末尾必须带
,否则
拼接出错
是核心,确保 PHP 加载的是
,而非主站的
若用不同 PHP 版本,需同步改
到对应 socket(如
)
如何让 v2 版本正确读取自己的配置和依赖
子目录项目不是“复制粘贴”就能跑,它仍需完整运行环境。常见坑包括:
文件路径错误:Laravel 或 ThinkPHP 默认从
上级找,但
下 public 路径变了,需在
中显式指定:
并重载
Composer autoload 冲突:主站和
若共用 vendor,可能加载错类;建议
单独
,并确保其
被正确引入
缓存路径冲突:
或
目录不能共用,否则 v1 写锁会导致 v2 报错;需在
或启动脚本中改写缓存根目录为
灰度流量控制的实际操作方式
子目录本身不提供流量比例控制,它只是“入口标识”。真实灰度要结合业务逻辑或前置网关——但在宝塔单机场景下,最简可行方案是:
前端 JS 或 App 根据灰度策略(如用户 ID 取模、cookie 标识)动态拼接 API 基地址:
vs
后端统一网关层(如用 Nginx
+
)分流到不同 upstream,但这就超出子目录范畴了
更轻量的做法:在主站入口
中判断请求头或 cookie,用
302 重定向(仅适合低频、非 API 场景)
真正要注意的反而是日志隔离——务必让
的 PHP 错误日志写入独立文件,否则和主站混在一起根本分不清问题来源。在子目录的
块里加上:
index.php/v2/rootfastcgi_param SCRIPT_FILENAME/v2/api/userv1/v2/index.phpserverlocation/v2/
location ^~ /v2/ {
alias /www/wwwroot/your-site.com/v2/;
index index.php;
try_files $uri $uri/ /v2/index.php?$query_string;
location ~ \.php$ {
fastcgi_pass unix:/tmp/php-cgi-80.sock;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_param SCRIPT_FILENAME $request_filename; # 注意这里!不是 $document_root$fastcgi_script_name
}alias/$request_filenameSCRIPT_FILENAME $request_filename/www/wwwroot/your-site.com/v2/index.phpindex.phpfastcgi_passphp-cgi-74.sock.envpublic//v2/v2/index.php$_ENV['APP_ENV'] = 'production';Dotenv::createImmutable(__DIR__.'/../');v2/v2/composer installvendor/autoload.phpstorage/runtime/v2/config/app.php../storage-v2/https://api.example.com/v2/https://api.example.com/mapsplit_clientsindex.phpheader('Location: /v2/...')v2/locationfastcgi_param PHP_VALUE "error_log=/www/wwwroot/your-site.com/v2-error.log";