frankenphp自身无进程守护能力,挂掉后需依赖外部管理器拉起;生产环境推荐systemd(配execstartpre检查、restart=on-failure),docker用restart: unless-stopped加主动healthcheck,supervisor则需注意sigterm不被优雅处理。

FrankenPHP挂掉后靠谁拉起?别指望它自己
FrankenPHP本身不带进程守护能力——它挂了就是挂了,不会自动重启。想实现“挂掉自动拉起”,必须在它外面套一层进程管理器。生产环境最稳妥的选择是 systemd,Docker 环境则直接用 restart: unless-stopped;Supervisor 也能用,但要注意 FrankenPHP 启动方式和信号兼容性。
systemd 配置要点:避免 silent fail
FrankenPHP 启动失败常表现为“秒退”,systemctl status frankenphp 显示 failed 但没具体错误。根本原因往往是启动脚本路径不对、权限不足或缺少 ExecStartPre 检查环节。
-
ExecStart必须用绝对路径,比如/var/www/myapp/vendor/bin/frankenphp -c /var/www/myapp/Caddyfile - 加
ExecStartPre=/usr/bin/test -x /var/www/myapp/vendor/bin/frankenphp,防止二进制不存在时静默失败 -
Restart=on-failure足够,不用always;搭配RestartSec=5避免密集重启触发 systemd 限流 - 务必设
User=www-data和WorkingDirectory=/var/www/myapp,否则 Caddyfile 中的相对路径或日志写入会失败
Docker 场景下 healthcheck 怎么写才不误判
只靠 restart: unless-stopped 不够——FrankenPHP 进程可能还在,但 HTTP 服务已卡死(比如 worker 全阻塞、TLS 握手 hang 住)。这时必须配 healthcheck 主动探测真实可用性。
- 别用
curl -f http://localhost/health这类简单请求:FrankenPHP 默认不带 /health 路由,得自己加一个返回 200 的 endpoint - 推荐用
test: ["CMD", "sh", "-c", "timeout 3 curl -sf http://localhost/health | grep -q 'ok'"],加timeout防卡死,-s静默输出避免日志刷屏 -
start_period: 40s很关键——FrankenPHP 初始化比 Nginx 慢,冷启动可能要 15~25 秒,太短会导致容器反复重启
Supervisor 管理 FrankenPHP 的坑:SIGTERM 处理不了
Supervisor 发 SIGTERM 停止 FrankenPHP 时,它不会优雅退出,而是立刻终止所有 worker 并退出主进程。这不是 bug,是 FrankenPHP 设计如此——它没有实现 pcntl_signal 捕获逻辑。所以用 Supervisor 时:
- 别设
stopwaitsecs太大(比如 30),FrankenPHP 收不到信号,Supervisor 会强行发SIGKILL,导致连接中断 -
autorestart=true可以用,但得确保startretries=1,避免因 Caddyfile 语法错连续重启 3 次后被 Supervisor 标记为FATAL - 日志重定向必须开:
redirect_stderr=true+stdout_logfile=...,否则frankenphp-worker.php报错会消失在黑洞里
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











