frankenphp 运行 symfony 实现无感发布的关键是启用 worker 模式(frankenphp_worker=1)并正确配置 php_worker 指向 public/index.php 绝对路径,配合 stop-workers 命令滚动更新。

FrankenPHP 跑 Symfony 时,发布无感的关键不在“重启服务”,而在绕过进程重启带来的请求中断——它本身不支持传统信号平滑 reload,但能靠 worker 模式 + 部署策略实现真正零停机。
worker 模式必须开启,且不能只靠 frankenphp-worker 命令临时启
默认的 FrankenPHP 普通模式(即没开 worker)每次改代码都要手动 kill 进程再启动,必然中断请求。真正的无感发布依赖其内置的 worker 生命周期管理:
-
FRANKENPHP_WORKER=1必须设为环境变量,不是可选项;否则frankenphp-worker启动后只是个孤立 CLI 进程,和 Caddy 主进程不联动 - worker 启动入口必须是 Symfony 的
public/index.php,不是bin/console或其他脚本;FrankenPHP 会自动复用这个入口做 autoload 和容器初始化 - 不要在 Caddyfile 里写
php_worker后直接跟exec php public/index.php—— 这样起的是 shell 子进程,FrankenPHP 无法接管生命周期,热更失败
Caddyfile 中的 php_worker 配置要匹配 Symfony 的真实入口路径
FrankenPHP 的 php_worker 指令不是转发器,而是告诉内嵌 PHP 运行时:“下次请求来时,别重新加载整个框架,复用这个已初始化的 worker 实例”。配置错路径会导致 worker 根本不生效:
- 路径必须指向
public/index.php,且是相对于 Caddy 工作目录的绝对路径,例如/var/www/myapp/public/index.php - 不能写成
./public/index.php或public/index.php—— Caddy 启动时 pwd 不一定等于项目根,worker 会找不到文件直接静默退出 - 如果用了自定义
APP_ENV,记得在 Caddyfile 里显式传:php_worker /var/www/myapp/public/index.php { env APP_ENV=prod } - 别漏掉
max_requests:设为1000或5000,避免单 worker 累积内存泄漏;FrankenPHP 会在达到后自动 fork 新 worker,旧 worker 处理完手上请求再退出
发布流程必须拆成两步:先换代码,再触发 worker 优雅重启
FrankenPHP 不监听 SIGHUP,但提供了 frankenphp stop-workers 命令配合 max_requests 实现可控滚动更新:
- 新版本代码部署到新目录(如
/var/www/myapp/releases/20261004-123456),软链current指向它 - 确保新代码的
public/index.php可读、var/cache可写、composer install --no-dev --optimize-autoloader已执行 - 执行
frankenphp stop-workers—— 它不会杀主进程,只通知所有活跃 worker 在完成当前请求后退出;新请求会由新 worker 接管(自动加载新代码) - 别用
systemctl restart frankenphp:这会强制中断所有连接,HTTP/2 流直接 reset,前端可能报net::ERR_CONNECTION_RESET
缓存与静态资源需独立处理,否则用户看到旧 CSS/JS
Symfony 的 assets:install 和 cache:warmup 在 worker 模式下行为和 FPM 不同:
-
cache:warmup必须在新 release 目录下执行,且要加--env=prod;worker 启动时只 warmup 当前APP_ENV对应的 cache,旧环境 cache 不影响 - 静态资源(CSS/JS)建议走
assets:install --symlink,而非复制;这样软链一换,Nginx/Caddy 下次读的就是新文件,不用清浏览器缓存 - 如果用了
Encore,构建产物必须放在public/build/下,且 Caddy 的root必须指向public,否则php_worker找不到入口,file_get_contents(/build/manifest.json)会失败
最易被忽略的一点:FrankenPHP 的 worker 不会自动感知 .env 文件变更。发布时若修改了数据库密码或 API key,必须确保新 release 目录下的 .env 已更新,且 APP_ENV 未被系统级环境变量覆盖——否则 worker 加载的还是旧配置。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











