FrankenPHP 可单独运行替代 Nginx + PHP-FPM:普通模式直接 frankenphp serve,生产模式搭配 Caddyfile 启用 HTTPS/HTTP/3;不建议与 Nginx 反向代理共用,除非已有 WAF 或多语言网关等特殊需求。

没有必要搭配使用,FrankenPHP 本身已内置 Web 服务器能力,直接替代 Nginx + PHP-FPM 整套栈。
FrankenPHP 不是 PHP-FPM 的增强版,也不是 Nginx 的插件——它是一个一体化应用服务器:把 Caddy(Web 服务、HTTPS 自动管理、HTTP/3、静态文件处理)和 PHP 运行时(embed SAPI)编译进同一个二进制,所有请求都在单进程内完成解析、路由、TLS 终止与 PHP 执行。
强行让 FrankenPHP 和 Nginx 配合,反而会引入冗余层、增加延迟、破坏 HTTPS 自动续期、丢失 worker 模式优势,属于典型“叠床架屋”。
✅ 正确用法:FrankenPHP 单独运行(推荐)
-
普通模式(适合小项目或快速验证)
直接启动,无需额外配置:frankenphp serve --document-root ./public
它自动监听
:8000,支持.php文件解析、静态资源服务、基础路由。立即学习“PHP免费学习笔记(深入)”;
-
生产模式(推荐搭配 Caddyfile)
创建Caddyfile:example.com { root * ./public php_backend encode zstd gzip file_server }启动:
frankenphp run
此时 FrankenPHP 充当 Caddy 的 PHP 扩展,自动启用 Let’s Encrypt、HTTP/3、日志、重写等全部能力。
❌ 不建议的组合方式(常见误区)
-
Nginx 反向代理到 FrankenPHP
虽然技术上可行(比如proxy_pass http://127.0.0.1:8000),但会导致:- TLS 被 Nginx 终止后,FrankenPHP 收到的是 HTTP 请求,无法正确识别
$_SERVER['HTTPS']; - 自动证书申请失效(Caddy 的 ACME 流程被 Nginx 拦截);
- 静态文件多走一次网络转发,失去零拷贝优势;
- 无法启用 worker 模式下的共享内存与长连接上下文。
- TLS 被 Nginx 终止后,FrankenPHP 收到的是 HTTP 请求,无法正确识别
Nginx 处理静态 + FrankenPHP 处理 PHP(类似传统分工)
FrankenPHP 本身就高效服务静态文件(比 Nginx 略慢但差距极小),且file_server指令已深度优化;再拆分不仅没收益,还让路由逻辑分散、缓存策略难统一。
⚙️ 特殊场景下“有限共存”的例外
仅在以下明确需求时,才考虑让 Nginx 位于 FrankenPHP 前方:
- 已有成熟 Nginx 集群(如 WAF、限流、IP 黑名单、复杂 rewrite 规则),且短期内无法迁移规则;
- 需要将多个不同语言服务(Go、Node、PHP)统一接入同一入口网关;
- 容器编排环境强制要求入口为 Nginx(如某些旧版 K8s Ingress Controller 不支持自定义 server)。
此时应:
- 让 Nginx 以 纯反向代理角色 工作(禁用所有 PHP 相关配置);
- 开启
proxy_http_version 1.1和proxy_set_header Upgrade $http_upgrade(保障 WebSocket/Mercure); - 在 FrankenPHP 中启用
X-Forwarded-*信任(通过FRANKENPHP_TRUSTED_PROXIES环境变量); - 关闭 FrankenPHP 的 HTTPS(由 Nginx 终止),并在 Caddyfile 中显式设为
http://协议。
FrankenPHP 的设计哲学就是“做减法”:用一个二进制取代 Nginx、PHP-FPM、certbot、supervisord 四件套。你不需要说服它去配合旧架构,而是让它自然接管——配置更少、链路更短、故障点更少、性能提升更实在。



















