宝塔 nginx 的 systemctl reload 静默不生效 (BT Panel nginx systemctl reload Is a Silent No-Op)
1. 触发场景
用宝塔面板装的 nginx(二进制在 /www/server/nginx/sbin/nginx),改完 vhost 后执行:
sudo systemctl reload nginx2. 症状
命令返回 0。systemctl status nginx 甚至显示:
Process: 10794 ExecReload=/etc/init.d/nginx reload (code=exited, status=0/SUCCESS)但新写的 vhost / 新换的证书就是没生效。于是你回去反复检查 vhost 文件、证书路径、nginx -t——全是对的,因为问题不在那。
3. 决定性判据
别信退出码,实测。 用一个只有新配置才会给出的特征去问 nginx:
# 新装了证书:问它现在给哪张证书
echo | openssl s_client -connect 127.0.0.1:443 -servername <新域名> 2>/dev/null | openssl x509 -noout -subject
# 或者直接拿新路径要内容
curl -s -o /dev/null -w "%{http_code}\n" https://<新域名>/<新路径>拿到旧行为 = 没生效。
4. 根因
宝塔的 nginx 由 /etc/init.d/nginx 管。systemd 看到的 nginx.service 是 sysv-generator 自动生成的壳(/run/systemd/generator.late/nginx.service):
ExecStart=/etc/init.d/nginx start
ExecStop=/etc/init.d/nginx stop
ExecReload=/etc/init.d/nginx reload
Type=forking
GuessMainPID=nosystemctl reload 实际是去跑这个 init 脚本的 reload 分支。在这台机器上它没有真正让正在跑的 nginx 重新读配置,退出码却是 0。
5. 修法
绕开 systemd,直接对二进制发信号:
sudo /www/server/nginx/sbin/nginx -t && sudo /www/server/nginx/sbin/nginx -s reload改完再实测一次(第 3 节),确认真的生效。
6. 下次如何识别
- 「reload 说成功了,但行为没变」→ 直接换
nginx -s reload重试,再实测。 - 在宝塔的机器上,默认用
nginx -s reload,不用 systemctl。注意二进制路径是宝塔的,不是/usr/sbin/nginx。 - 这类「退出码 0 但没生效」的坑不只出现在 nginx:凡是靠退出码判断成功的地方,都要补一个行为断言——证书看 subject、接口看响应、文件看内容。
7. 相关
- 本机通、公网 403——容器前的域名转发层 (Loopback OK but Public 403 — Domain Forwarding Layer) —— 同一台机器上同一次排查里踩到的另一层;「实测验证」这个习惯在那篇里也是决定性的。
- platform deploy.sh 首次部署不生效 (Nginx Deploy Copy-Order Bug) —— 另一个「命令跑完但配置没上线」的案例,那篇是部署脚本的复制顺序问题。
来源:2026-09-22 在 LA 小鸡(宝塔面板,nginx 1.28.1)上新增 vhost。systemctl reload nginx返回 0、status 显示 SUCCESS,但openssl s_client仍拿到旧证书;改用/www/server/nginx/sbin/nginx -s reload后立刻生效。
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Network