FrankenPHP部署Laravel无需改代码,但不可误以为能编译PHP;需用frankenphp serve验证、确保autoload加载、扩展可用、打包前清理并禁用UPX压缩,Caddyfile路径要正确,队列与定时任务须独立管理。

FrankenPHP 部署 Laravel 项目不需要改代码,但必须避开「以为它能像 Go 那样编译进二进制」这个最大误区——它打包的是「frankenphp 二进制 + 你的 PHP 文件集合」,不是编译 PHP 代码。
确认经典模式能否直接跑通
这是最快验证路径:不装 Octane、不写 Caddyfile、不配 systemd,只用内置服务启动。
-
frankenphp serve --worker=public/index.php是最轻量的启动命令,等效于php -S,但支持 HTTPS 和 HTTP/3 - 确保
public/index.php存在且可读(chmod 644 public/index.php),Laravel 的.env已配置好APP_ENV=prod和APP_DEBUG=false - 常见失败现象:
500 Internal Server Error且日志里出现Class 'Illuminate\Foundation\Application' not found→ 说明vendor/autoload.php没加载到,检查是否漏了composer install --no-dev --optimize-autoloader - 如果报
Failed to load extension 'pdo_mysql',运行frankenphp php-cli -m | grep pdo确认扩展是否存在;缺失需换带该扩展的 FrankenPHP 二进制或用 Docker 镜像重装
用 frankenphp build 打包成单文件
这一步生成的是「可分发的独立可执行文件」,但本质仍是解压后运行 PHP 明文文件,不是真正编译。
- 必须在 Laravel 项目根目录执行:
frankenphp build --output myapp --server-name localhost;--server-name决定 Let's Encrypt 域名证书申请目标,本地测试填localhost即可 - 打包前务必清理:
rm -rf .git tests/ vendor/bin/ storage/logs/ storage/framework/cache/,否则二进制体积暴涨且可能泄漏敏感路径 -
--no-compress强烈建议加上,尤其首次调试时——UPX 压缩会掩盖真实错误,比如权限不足或扩展缺失,报错会变成模糊的segmentation fault - 生成的
myapp文件是 Linux/macOS 可执行文件,Windows 不支持;运行前需chmod +x myapp,否则提示Permission denied
Caddyfile 配置容易被忽略的细节
FrankenPHP 默认行为是找当前目录下的 Caddyfile,但很多教程没说清路径怎么写才不翻车。
立即学习“PHP免费学习笔记(深入)”;
- root 路径必须写成
root * public/(结尾带斜杠),写成root * ./public或root * /app/public在打包后大概率 404——因为打包解压路径不确定,相对路径更可靠 - 如果你用
frankenphp build,它会自动嵌入一个最小化 Caddyfile;但若手动提供,必须包含php_server指令,不能只写reverse_proxy - 静态资源缓存要显式开启:
encode zstd gzip和file_server块里加cache,否则 CSS/JS 不走缓存,TTFB 偏高 - 别在 Caddyfile 里硬编码
fastcgi_pass或proxy_pass——FrankenPHP 不走 FastCGI,这类配置会被忽略甚至引发 panic
队列和定时任务必须独立管理
FrankenPHP 只管 HTTP 请求生命周期,queue:work 和 schedule:run 完全不在它的职责范围内,强行塞一起只会出 silent failure。
- 队列 worker 必须用 Supervisor 或 systemd 单独拉起:
php /path/to/artisan queue:work --tries=3 --sleep=3,不要依赖 FrankenPHP 进程自动启动 - 定时任务只能走系统 cron:
* * * * * cd /path/to/project && php artisan schedule:run >> /dev/null 2>&1;用schedule:work会额外占一个常驻 PHP 进程,和 FrankenPHP 的内存优化目标冲突 - 关键检查点:
QUEUE_CONNECTION=redis时,确保REDIS_HOST指向的是宿主机或 Docker 网络内可解析的地址,不是127.0.0.1(容器内会连自己) - 所有 CLI 命令(包括
php artisan config:clear)必须在打包前执行完毕,打包后的二进制里没有 Artisan 命令行入口
真正麻烦的从来不是打包命令本身,而是 vendor 目录里那些没声明但 runtime 依赖的扩展,比如 ext-xml 或 ext-curl——它们不会在 composer install 报错,却会在 frankenphp php-cli -m 里消失。每次换 FrankenPHP 版本,都得重新核对一遍 php-cli -m 输出。



















