FrankenPHP默认运行普通模式,Worker模式需在Caddyfile中显式配置worker块并指定合法绝对路径的入口脚本,否则不启用;该模式要求依赖扩展、环境变量和php.ini设置均提前就绪,且须通过metrics或响应头等多方式验证生效。

Worker模式必须显式启用,不是默认行为
FrankenPHP 容器启动后默认走的是「普通模式」——即每个请求都新建 PHP 生命周期,和传统 PHP-FPM 行为一致。Worker 模式需要在 Caddyfile 里明确配置 worker 块,并指定入口脚本路径,否则不会激活。Docker 镜像(如 dunglas/frankenphp:latest)本身不自动开启该模式,也不会读取项目目录下的 server.php 或 frankenphp-worker.php 等文件,一切以 Caddyfile 为准。
关键配置项:worker { file ... } 必须存在且路径正确
在 Caddyfile 的站点块内添加 worker 子块,最简可用写法如下:
localhost {
route {
php {
root /app/public
}
}
worker {
file /app/worker.php
}
}
注意几个硬性要求:
-
file路径必须是容器内绝对路径,不能是相对路径或未挂载的宿主机路径 - 该文件必须存在且可读,FrankenPHP 启动时会校验,失败直接报错退出,错误信息类似:
failed to load worker script: open /app/worker.php: no such file or directory - Laravel 项目需先安装
laravel/octane,并用php artisan octane:workers --server=frankenphp生成worker.php;ThinkPHP6 则需按文档改写入口,用frankenphp_handle_request()包裹逻辑 - 不支持直接用
index.php当 worker 入口,它缺少常驻所需的生命周期管理逻辑
环境变量与扩展依赖容易漏配
Worker 模式下 PHP 进程常驻,所有初始化只做一次,因此启动前的扩展、INI 设置、环境变量必须一步到位:
立即学习“PHP免费学习笔记(深入)”;
- 确认容器内已装齐依赖扩展,例如 Laravel 需要
pcntl(队列信号处理)、redis(缓存)、opcache(加速),可用frankenphp php-cli -m | grep pcntl验证 - 若用
install-php-extensions安装扩展,务必在COPY . /app之后、frankenphp启动之前执行,否则扩展不在运行时生效 - 环境变量(如
APP_ENV、DB_HOST)需通过worker { env KEY VALUE }显式注入,不能只靠 Docker-e或.env文件——后者仅对 CLI 启动有效,worker 进程不读取 -
php_ini指令可用于覆盖关键配置,比如php_ini opcache.enable 1,但注意某些 INI 项(如max_execution_time)在常驻模式下意义已不同
验证是否真跑在 Worker 模式
光看进程名或日志不够,得从指标和行为两层交叉确认:
- 访问
http://localhost:2019/metrics(Caddy admin 端点),搜索frankenphp_worker_开头的指标,有数据说明 worker 已注册;若只有frankenphp_total_threads等线程级指标,说明 worker 未生效 - 发两个请求,用
curl -v观察响应头,Worker 模式下X-Powered-By通常带FrankenPHP/worker标识(取决于框架封装) - 故意在
worker.php里加sleep(5),再并发请求,如果第二个请求没卡住而是立刻返回,说明线程复用成功;反之若全部阻塞,大概率是num设太小或脚本卡死没释放线程
最常被忽略的是:worker 脚本里不能有全局资源泄漏(如未关闭的 PDO 连接、未 unset 的大数组),这类问题在普通模式下无感,但在常驻模式下会随请求累积,几小时后内存爆掉或连接数打满。



















