升级 PHP,本来是想把网站维护好一点,结果版本刚切过去,WordPress 后台就变成了 502 Bad Gateway。
我这次把主网站从 PHP 8.2.31 升级到 PHP 8.3.36。新版本装好了,扩展也补齐了,PHP-FPM 显示正常运行,但网站还是打不开。
最后查出来,问题出在 Nginx 没有权限连接 PHP 8.3 的套接字。另外还发现,我这台服务器上有两套 Nginx,宝塔里修改的配置,并不是网站实际使用的那一套。
日志里真正指明方向的是这一句:
(13: Permission denied) while connecting to upstream
这篇把我当时怎么查、怎么回退、最后怎么修好的过程记下来。
故障发生于 2026 年 10 月 28 日,后续验证完成于 10 月 29 日。PHP 8.3.36 是这次升级使用的版本,不代表你阅读时的最新版本。
一、为什么要升级 PHP?
我的网站使用 WordPress,服务器是 InterServer VPS,系统是 Ubuntu,装了宝塔面板。
之前站点健康里提示 PHP 版本较旧。我先安装了 PHP 8.3.36,又给新版本补上 OPcache、fileinfo、Imagick 和 exif。
安装后检查,扩展能加载,PHP-FPM 配置测试也通过了。
但到这里,只能说明 PHP 本身准备好了,还不能说明网站已经能正常使用它。后面的问题,就是在网站与 PHP 的连接上。
二、宝塔切到了 PHP 8.3,WordPress 为什么还显示 8.2?
我先在宝塔的网站设置里选择 PHP 8.3,切换后再看 WordPress 的站点健康,里面仍然显示 PHP 8.2.31。
一开始以为是页面没刷新。后来检查宝塔的网站配置,确实已经指向 PHP 8.3:
include enable-php-83.conf;
对应的转发配置也没有写错:
fastcgi_pass unix:/tmp/php-cgi-83.sock;
但重新加载宝塔 Nginx 时,终端报错:
nginx: [alert] kill(75905, 1) failed (3: No such process)
意思是,它按照 PID 文件找到的那个进程,已经不存在了。
继续查看运行中的 Nginx,才发现实际提供网站服务的是:
/usr/sbin/nginx
而刚才检查和操作的是:
/www/server/nginx/sbin/nginx
两套 Nginx,不是同一份配置。宝塔里显示切换成功,不代表正在运行的网站已经切过去。
我主网站实际使用的配置位于:
/etc/nginx/sites-enabled/liuqiangwujinjidian.com
里面仍然写着:
fastcgi_pass unix:/tmp/php-cgi-82.sock;
所以 WordPress 显示 PHP 8.2,并没有显示错。
三、改了实际配置,网站却出现 502
找到真正生效的配置后,我先备份,再把主网站的 PHP 转发地址改成:
fastcgi_pass unix:/tmp/php-cgi-83.sock;
然后检查系统 Nginx 配置:
/usr/sbin/nginx -t
检查通过,再重新加载:
systemctl reload nginx
命令没有报错。但回到浏览器,WordPress 登录页出现:
502 Bad Gateway
nginx/1.24.0 (Ubuntu)
配置检查通过,不等于网站请求一定能跑通。这次 Nginx 配置语法没问题,PHP 8.3 也正在运行,但两者之间还是没有连上。
四、先回退到 PHP 8.2,再查原因
网站已经打不开,我没有继续在 PHP 8.3 上反复试,而是先恢复原来的连接。
把主网站配置中的:
fastcgi_pass unix:/tmp/php-cgi-83.sock;
改回:
fastcgi_pass unix:/tmp/php-cgi-82.sock;
再次检查并重新加载:
/usr/sbin/nginx -t && systemctl reload nginx
这次升级前,PHP 8.2 没有卸载,原来的连接也还在,所以可以先切回去。
对我这种自己维护网站的人来说,升级时保留旧版本很有必要。新版本有问题,至少还有一条回去的路。
五、日志指出了真正的问题:Permission denied
接下来查看主网站的 Nginx 错误日志:
tail -n 20 /var/log/nginx/liuqiangwujinjidian.com.error.log
日志里反复出现:
connect() to unix:/tmp/php-cgi-83.sock failed
(13: Permission denied) while connecting to upstream
这条信息很关键:Nginx 想连接 PHP 8.3,但被权限挡住了。
再比较新旧两个套接字:
ls -l /tmp/php-cgi-82.sock /tmp/php-cgi-83.sock
结果是:
srw-rw---- 1 www www-data ... /tmp/php-cgi-82.sock
srw------- 1 www www ... /tmp/php-cgi-83.sock
查看 Nginx 工作进程使用的用户和组:
ps -eo user,group,pid,args | grep '[n]ginx: worker'
我这台服务器显示的用户和组都是:
www-data www-data
问题就清楚了:
| 项目 | PHP 8.2 | PHP 8.3 |
|---|---|---|
| 套接字所属用户 | www | www |
| 套接字所属组 | www-data | www |
| 权限 | 0660 | 0600 |
| Nginx 的 www-data 组能否连接 | 可以 | 没有对应权限 |
这里说的套接字,可以理解成 Nginx 把 PHP 请求交给 PHP-FPM 的本机连接入口。
PHP 8.3 虽然启动了,但它创建的入口只允许 www 用户访问。我的系统 Nginx 使用 www-data,自然就连不上。
这次 502 的直接原因是连接权限,还没到判断 WordPress 插件是否兼容那一步。
六、在 PHP-FPM 配置中修正权限
PHP 8.3 当时的配置是:
listen = /tmp/php-cgi-83.sock
listen.owner = www
listen.group = www
listen.mode = 0600
我先备份配置文件:
cp -a /www/server/php/83/etc/php-fpm.conf \
/www/server/php/83/etc/php-fpm.conf.before-socket-fix
再把对应设置改为:
listen = /tmp/php-cgi-83.sock
listen.owner = www
listen.group = www-data
listen.mode = 0660
这里没有改 PHP 工作进程的运行用户,也没有把权限直接放到所有人都能访问,而是让套接字所属组与实际连接它的 Nginx 对应上。
修改后检查:
/www/server/php/83/sbin/php-fpm -t
终端显示配置测试成功。
这些路径、用户和组是我这台服务器上的实际情况。别人的服务器不一定相同,不能只看到 Permission denied,就直接照搬 www-data。
七、重新加载后,权限居然没变
配置改好后,我先运行:
/etc/init.d/php-fpm-83 reload
终端显示:
Reload service php-fpm done
但再查看套接字,仍然是:
srw------- 1 www www ... /tmp/php-cgi-83.sock
又重新加载了一次,结果还是一样。
终端显示 done,不代表我想修改的权限已经生效。
这次 reload 后,看到的套接字时间、所属组和权限都没有变化;仅凭这些现象,不能确定 reload 内部具体发生了什么。我随后重启的是宝塔 PHP 8.3 服务:
/etc/init.d/php-fpm-83 restart
再检查运行状态和套接字:
/etc/init.d/php-fpm-83 status
ls -l /tmp/php-cgi-83.sock
这次终于变成:
srw-rw---- 1 www www-data ... /tmp/php-cgi-83.sock
新配置对应的权限生效了。
操作这一步时,主网站仍然使用 PHP 8.2;另一个网站连接的是另一套系统 PHP-FPM。我先确认了服务范围,再重启宝塔 PHP 8.3。
八、再次切换,WordPress 才真正用上 PHP 8.3
权限修好后,我把主网站实际 Nginx 配置里的连接地址,再次改为:
fastcgi_pass unix:/tmp/php-cgi-83.sock;
检查并重新加载:
/usr/sbin/nginx -t && systemctl reload nginx
这次回到 WordPress 后台,站点健康显示:
PHP 版本:8.3.36
PHP SAPI:fpm-fcgi
首页、文章页和后台可以正常打开,此前配置的 Redis 对象缓存也保持已连接,站点健康检查通过。
到这里,才算这次升级完成。
九、这次维护,我记住了几件事
第一,先确认网站到底由哪套服务运行。
服务器装了宝塔,不代表正在使用的就是宝塔 Nginx。只在面板里改版本,可能没有改到实际配置。
第二,出现 502,先看日志。
我这次日志已经写明 Permission denied。如果不看日志,直接停插件、改主题,很可能忙半天也碰不到原因。
第三,服务启动了,不等于 Nginx 能连接。
PHP-FPM 正常运行、套接字正在监听,都不代表连接权限一定正确。
第四,修改后要检查实际结果。
这次 reload 显示完成,但套接字权限没有变化。最后是重启对应 PHP 服务后,才确认生效。
第五,升级前做备份,旧版本先保留。
我提前做了网站备份,也备份了实际配置。遇到问题先回退,再慢慢查,比网站一直挂着更踏实。
VPS 月费便宜,是我选择自己建站的原因。但这次也让我更清楚:服务器账单只是成本的一部分,维护时间也得算进去。
相关阅读
这次升级运行在我的 InterServer VPS 上,套餐费用和日常维护感受见每月 6 美元的 InterServer VPS 建站体验;后续的中国电信访问记录则单独说明测试条件与请求耗时。
[…] 这次网站维护中,我补装了 PHP 扩展、配置 Redis,并把主网站切换到 PHP 8.3.36。切换时曾出现 502,最后查到系统 Nginx 无权连接新 PHP 的套接字,修正权限后才恢复。PHP 升级故障记录中保留了回退、日志和修复步骤。这是我的一次故障记录,不能把“有面板”理解成以后不需要维护,也不能把一次故障归结为服务器性能差。 […]
[…] 确认已经重新登录服务器后,可以继续看我实际处理的两次问题:Redis 安装后,服务启动与 WordPress 对象缓存接入的排查,以及升级 PHP 后出现 502,如何从日志找到套接字权限问题。这两篇记录的是服务器内部的问题,与本文输错命令位置的情况不同。 […]