页面打不开不是 Nginx 的错

SSL 证书签发成功,伪静态规则配置完成,运行目录指向了 public。但是页面就是打不开。

顺手拿 http:// 开头的地址试一下,它很配合地 301 跳到了 https://。

到这儿我以为部署完了。然后去访问接口地址------页面打不开。

没有 502,没有 404 页面,没有 PHP 报错。浏览器上就是一片空白,或者一句「无法访问此网站」。

这时候最常见的反应是回去翻 Nginx 配置:是不是 location 写错了?伪静态规则不对?server_name 没匹配上?

都不是。

这批机器是 1Panel + OpenResty + PHP 容器,站点跑的是 ThinkPHP 8,刚做完首次部署的验收。

关键在于问一句:刚才那个 301 跳转,是谁干的。

是 Nginx,在这儿就是 OpenResty。它要干成这件事,得同时满足 3 条:进程在监听 80 端口;server_name 匹配上了这个域名;跳转规则不管是 return 301 还是 rewrite,被正确执行。

3 条全成立,跳转才会成功。

所以跳转成功这件事本身就是一份体检报告。没监听、端口没放行,表现是连接被拒绝或者超时。证书有问题,表现是证书错误、UNABLE_TO_VERIFY_LEAF_SIGNATURE。后端 PHP 挂了但 Nginx 正常,表现是能连上、能跳转,但页面空白或 5xx。

第三种就是当时的情况。问题一定在跳转之后的处理环节,也就是 PHP。

这个判断把排查范围从整个 Web 栈直接压到了 PHP 应用,省掉大量瞎猜。

往下一层,看入口文件。PHP 站点的入口通常是 public/index.php,而这个文件的第一行有效代码几乎都是同一句:

php 复制代码
require __DIR__ . '/../vendor/autoload.php';

vendor/ 不存在,这一行就让 PHP 进程直接崩。

注意严重程度:这不是某个函数调用失败,也不是某个页面返回错误,这是加载阶段的 Fatal error。

区别在于:框架已经跑起来、只是路由匹配不上,你会看到一个 404 页面,甚至是框架自带样式的错误页;vendor 缺失,框架根本没被加载,连优雅地报一个错的能力都没有。

所以最后看到的是「页面打不开」,而不是 404。它连 404 都渲染不出来。

vendor/ 为什么永远不会自己出现,这才是这篇真正值得记的地方。

两件事叠在一起。一是 .gitignore 里写了 /vendor,git clone 下来的仓库天然不含 vendor/,这是 PHP 项目的通行做法,依赖不进版本库。二是部署脚本的 rsync 排除清单里也写了 vendor/,这一条本身正确且必要,否则每次更新代码都会把服务器上装好的依赖删光。

两条都没错。于是结果就是这个站点目录里不会有 vendor/,而且永远不会自己出现。

那它从哪来?只能原地装。

bash 复制代码
composer install --no-dev

仓库里带了 composer.lock 的话,这一步就是可复现的------严格按锁定版本安装,不随服务器 PHP 版本浮动。所以 composer.lock 务必纳入版本控制。

症结在于:排除清单和启动必需件,是同一批文件。

rsync 要排除 .env、vendor/、runtime/,理由是它们不是代码、不该被同步覆盖。可它们又都是必须存在的东西。

排除不等于不需要,只是不由同步来负责。

部署流程如果只写了排除什么,却没写排除之后由谁生成,就一定会漏,而且漏得毫无察觉:rsync 不回显任何异常,目录列表看起来完全正常,直到你去访问站点。

装完依赖再访问,页面有反应了。错误换了个样子。

第 2 层:.env 也不在。

它和 vendor/ 是同一个原因:.gitignore 忽略了它,rsync 排除清单里也有它。所以数据库配置、密钥全是空的。表现出来是能访问了,但数据库连不上。

第 3 层:请求的地址本身可能就是错的。

这层最容易被忽略,因为前两层修好之后,报错信息会突然变得很像业务问题。当时访问的是 /api/index/ping,回显四个字:方法不存在。

这条回显含金量很高。它证明框架已经完全跑起来了,能实例化控制器、能查路由表,只是路由表里没有这一条。

所以它恰好出现在前两层修好之后、第 3 层修好之前,把三层问题的修复时序直接打了出来。

去路由文件里核对,这个动作确实存在,只是注册在另一个分组下:

bash 复制代码
实际访问:  /api/index/ping
正确地址:  /api/auth/ping

改对地址,接口回 pong。从「打不开」到「方法不存在」再到「pong」,报错是一条收敛路径------前两层没修好之前,第 3 层根本不会暴露。

相关推荐
量化分析码农2 小时前
【Python量化系统工程实战 #06】从本地脚本到云端部署:量化系统的最小可运行架构
后端
ALONE阿龙太原微码2 小时前
RBAC 以及主流权限模型
后端
斑鸠喳喳2 小时前
线程本地存储 ThreadLocal
java·后端
你顶住我先撤2 小时前
RocketMQ 消息类型
后端
liangshanbo12152 小时前
高级前端面试题:package.json 常见字段
前端·json
CappuccinoRose3 小时前
输入事件进阶
前端·javascript·输入事件
高频因子挖掘机3 小时前
批量行情返回后,怎样把请求失败的股票单独挑出来?
后端·github·api
小蒜学长4 小时前
在线保险服务与管理平台的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·服务平台·在线保险
liangshanbo12154 小时前
面试题:前端工程化中 Tree Shaking的原理是什么?
前端·treeshaking