news 2026/9/15 20:00:30

使用 FrankenPHP 部署 WordPress:从零安装、生产级 Caddyfile 到热重载完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 FrankenPHP 部署 WordPress:从零安装、生产级 Caddyfile 到热重载完整指南

使用 FrankenPHP 部署 WordPress:从零安装、生产级 Caddyfile 到热重载完整指南

【免费下载链接】frankenphp🧟 The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp

本文以 FrankenPHP 官方文档(docs/es/wordpress.md,英文版见 docs/wordpress.md)为主体,系统讲解如何在 WordPress 站点上启用 FrankenPHP:先用php-server命令完成最小安装,再通过Caddyfile搭建生产级配置(自动 HTTPS、HTTP/3、Zstandard/Brotli/Gzip 压缩),最后结合内置 Mercure 中心为 WordPress 主题接入热重载(hot reload)开发工作流。读完本文,你将掌握一套可直接落地的 WordPress + FrankenPHP 部署与开发方案。

为什么用 FrankenPHP 运行 WordPress

FrankenPHP 是一个基于 Caddy 构建的现代 PHP 应用服务器,PHP 解释器直接内嵌于进程之中,无需单独的 PHP-FPM 进程。将 WordPress 跑在 FrankenPHP 上可以获得一套现代、高性能的栈:自动 HTTPS 证书签发与续期、HTTP/3 支持、Zstandard(zstd)压缩等,均由 Caddy 与 FrankenPHP 原生产出。此外,FrankenPHP 内置的 Mercure 中心与 hot reload 功能,能让 WordPress 主题开发做到"改完即刷新",大幅提升开发体验。

WordPress 最小安装:一条命令跑起来

官方文档给出的最小安装路径极其简单,只需 5 步:

  1. 从 WordPress 官网下载 WordPress 安装包;

  2. 解压 ZIP 压缩包,并在解压出的目录中打开终端;

  3. 执行启动命令:

    frankenphp php-server
  4. 浏览器访问http://localhost/wp-admin/,按提示完成 WordPress 安装向导;

  5. 完成。

php-server是 FrankenPHP 提供的一个"开箱即用的生产级 PHP 服务器"子命令,其实现位于 caddy/php-server.go。从源码看(cmdPHPServer函数),该命令在底层做了这些事:默认监听:80端口、将.php作为脚本扩展名、自动生成try_files回退规则(优先匹配现有文件,其次index.php,最终回落到文件服务器),并在启动时默认启用 zstd、br、gzip 三层压缩编码。也就是说,这一条命令已经自带压缩、静态文件服务与 PHP 执行能力,适合快速演示与开发。

php-server还支持若干有用参数(均见 caddy/php-server.go 的 flag 定义):

参数简写作用
--domain-d指定域名,启用 HTTPS 并切换到 443 端口
--root-r指定站点根目录
--listen-l自定义监听地址
--worker-w指定 worker 脚本(可重复)
--watch监视文件变化(常与 hot reload 搭配)
--access-log-a启用访问日志
--debug-v输出详细调试日志
--mercure-m启用内置 Mercure 中心
--no-compress关闭 zstd、br、gzip 压缩

例如本地用 HTTPS 域名方式启动:frankenphp php-server --domain=example.com,此时默认监听端口会切换到 443 并使用 HTTPS(源码中通过certmagic.HTTPSPort实现)。

生产级配置:用frankenphp run配合 Caddyfile

最小安装适合演示,若要用于生产,官方文档推荐使用frankenphp run配合一个Caddyfile。以下配置来自 docs/es/wordpress.md(与英文版 docs/wordpress.md 一致):

example.com php_server encode zstd br gzip log

逐行拆解:

  • example.com:站点地址。FrankenPHP 会为该域名自动签发并维护 HTTPS 证书(同时监听 443 端口支持 HTTP/3),只要域名的 A/AAAA 记录指向服务器即可;
  • php_server:Caddy 指令,作用等价于"先尝试匹配 PHP 文件,其余交给静态文件服务",是大多数应用的最佳选择(若需要完全掌控可改用底层php指令,详见 docs/config.md 的php_server/php指令说明);
  • encode zstd br gzip:开启响应压缩,编码优先级为 Zstandard → Brotli → Gzip,浏览器支持哪种就协商哪种;
  • log:开启访问日志,便于生产排障。

php_server指令的常用子选项

php_server是 Caddyfile 站点块中的高级指令,支持多种子选项(完整列表见 docs/config.md)。与 WordPress 部署最相关的几个:

example.com root public/ # 显式指定站点根目录(WordPress 推荐将根目录指到 wp 源码目录) php_server { root public/ # 与上方等价,可写在这里 env WP_ENV production # 为 PHP 注入环境变量 request_body_timeout 60s # 请求体读超时,默认 60s,0 表示禁用 # worker { # worker 模式按需开启,见下文 # file index.php # } }

注意:FrankenPHP 默认会为所有主机名(包括localhost)自动启用 HTTPS。如果开发环境想关闭,可在启动时设置SERVER_NAME环境变量为http://:80(详见 docs/config.md 的"Disabling HTTPS"一节)。此外,官方仓库还提供了一个带注释的完整 Caddyfile 模板(caddy/frankenphp/Caddyfile),其中包含了 Mercure 的注释配置与SERVER_NAMESERVER_ROOTFRANKENPHP_CONFIG等便捷环境变量,可直接作为生产起点。

进阶:WordPress 与 worker 模式

若你的 WordPress 站点启用了任意插件或自定义代码把 PHP 常驻内存(worker 模式),请阅读 docs/worker.md。worker 模式让应用只启动一次,之后请求处理只需数毫秒,但代价是代码改动不会即时生效——这正是下文 hot reload 要解决的核心痛点之一。

为 WordPress 启用热重载(Hot Reload)

Hot reload 是 FrankenPHP 面向开发环境的招牌功能:当工作目录中的 PHP、模板、JS、CSS 等文件发生变化时,浏览器无需手动刷新即可实时更新页面,工作流类似前端工具链中的 HMR(Hot Module Replacement)。官方明确指出该功能"原生兼容 WordPress、Laravel、Symfony 以及任何其他 PHP 应用或框架"(见 docs/hot-reload.md)。

其工作链路如下(详见 docs/hot-reload.md 的"How FrankenPHP hot reload works"一节):

  1. FrankenPHP 底层基于e-dant/watcher库监视文件系统变化(caddy/hotreload.go中定义了默认监视模式);
  2. 文件变化时,将变更文件列表封装为 JSON 推送到内置的 Mercure 中心;
  3. 浏览器端的 JS 库订阅 Mercure 事件;
  4. 若页面加载了 Idiomorph 库,则对 DOM 进行 morph(保留滚动位置与输入状态);否则执行整页刷新。

第一步:在 Caddyfile 中开启 Mercure 与 hot_reload

热重载依赖内置的 Mercure 中心来推送事件,因此在 Caddyfile 中需要同时启用 Mercure 与hot_reload子指令(配置示例来自 docs/es/wordpress.md):

localhost mercure { anonymous } php_server { hot_reload }
  • mercure { anonymous }:启用内置 Mercure 中心,anonymous允许无 JWT 的匿名订阅者(浏览器端订阅事件不需要鉴权);
  • php_server { hot_reload }:在php_server指令下挂上hot_reload子指令。

从源码看(caddy/hotreload.go),configureHotReload会做两件事:把监视目录与 Mercure hub 通过frankenphp.WithHotReload()注入 PHP 线程选项;同时向每个请求注入名为FRANKENPHP_HOT_RELOAD的环境变量,其值形如/.well-known/mercure?topic=<topic>,供 PHP 侧读取订阅地址。若未配置 Mercure 就开启hot_reload,FrankenPHP 会直接报错unable to enable hot reloading: no Mercure hub configured

默认情况下,FrankenPHP 会监视当前工作目录下匹配以下 glob 模式的所有文件:

./**/*.{css,env,gif,htm,html,jpg,jpeg,js,mjs,php,png,svg,twig,webp,xml,yaml,yml}

也可以显式指定要监视的文件/目录(支持 glob 语法):

php_server { hot_reload src/**/*{.php,.js} config/**/*.yaml }

或使用长格式,自定义 Mercure topic 与多个监视路径:

php_server { hot_reload { topic hot-reload-topic watch src/**/*.php watch assets/**/*.{ts,json} watch templates/ watch public/css/ } }

[!WARNING] hot reload仅适用于开发环境。官方文档明确警告:该功能会暴露敏感的内部细节并拖慢应用,切勿在生产环境开启(见 docs/hot-reload.md)。

第二步:在主题的 functions.php 中注入客户端脚本

WordPress 服务端检测到文件变化后,浏览器还需要订阅事件才能完成页面更新。官方文档给出的做法是:在主题的functions.php中通过wp_head动作注入两段 JS(代码来自 docs/es/wordpress.md):

// wp-content/themes/<your-theme>/functions.php function hot_reload() { ?> <?php if (isset($_SERVER['FRANKENPHP_HOT_RELOAD'])): ?> <meta name="frankenphp-hot-reload:url" content="<?=$_SERVER['FRANKENPHP_HOT_RELOAD']?>"> <script src="https://cdn.jsdelivr.net/npm/idiomorph"></script> <script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"></script> <?php endif ?> <?php } add_action('wp_head', 'hot_reload');

关键点说明:

  • $_SERVER['FRANKENPHP_HOT_RELOAD']:由 FrankenPHP 注入的环境变量(见 caddy/hotreload.go),内容为 Mercure 订阅地址。isset()判断保证未开启 hot reload 时页面零额外开销;
  • <meta name="frankenphp-hot-reload:url" ...>:把订阅地址暴露给前端库;
  • idiomorph:DOM morphing 库,加载后热更新会保留滚动位置与输入状态,而不是粗暴整页刷新;
  • frankenphp-hot-reload/+esm:官方提供的前端库,自动订阅 Mercure 中心、后台拉取最新页面内容并完成 DOM 更新。

第三步:启动

一切就绪后,在 WordPress 根目录执行:

frankenphp run

frankenphp run会读取当前目录下的Caddyfile并启动 Caddy(FrankenPHP 默认在启动目录查找Caddyfile,也可用-c指定路径)。此后,无论是修改主题的functions.php、模板文件还是 CSS,浏览器都会自动刷新或 morph 更新。

进阶技巧

  • 保留特定 DOM 节点:个别场景(如 Symfony Web Debug 工具条等开发工具)希望某些节点不被 morph 替换,可给对应元素加上data-frankenphp-hot-reload-preserve属性(见 docs/hot-reload.md)。
  • 与 worker 模式组合:如果你的 WordPress 应用开启了 worker 模式,PHP 常驻内存意味着改代码后 worker 不会自动重启。此时应同时配置worker { watch }让 worker 随文件变化重启,与hot_reload形成"浏览器刷新 + worker 重启"的完整开发闭环(示例见 docs/hot-reload.md)。
  • 手动实现客户端逻辑:不想引入官方 JS 库时,也可用原生EventSource直接订阅 Mercure 中心事件(订阅路径为/.well-known/mercure?topic=...),完整的订阅与发布示例见 docs/mercure.md。

小结

围绕 WordPress 这个具体场景,FrankenPHP 给出了从"一条命令启动"到"生产级 Caddyfile"再到"开发期热重载"的完整路径:

  • 快速上手frankenphp php-server,一条命令即可访问wp-admin完成安装;
  • 生产部署frankenphp run+Caddyfile,自动 HTTPS、HTTP/3、zstd/br/gzip 压缩一站式解决;
  • 开发体验mercure { anonymous }+php_server { hot_reload }+ 主题functions.php注入脚本,改完即所见,保留页面状态。

如需深入了解热重载的完整工作原理与全部配置项,可继续阅读 docs/hot-reload.md、docs/mercure.md 与 docs/config.md;对应实现源码位于 caddy/hotreload.go 与 caddy/php-server.go。

【免费下载链接】frankenphp🧟 The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 19:59:09

如何用 Docker 首次运行 Telegraf 并确认指标开始输出?

如何用 Docker 首次运行 Telegraf 并确认指标开始输出&#xff1f; 【免费下载链接】telegraf Agent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data. 项目地址: https://gitcode.com/GitHub_Trending/te/telegraf 这篇…

作者头像 李华
网站建设 2026/9/15 19:57:59

VS2017配置PCL 1.9.1:Windows点云开发环境搭建与排错全攻略

VS2017配置PCL 1.9.1&#xff0c;win10系统下几乎是每个入门点云处理的同学都要迈的一道坎。说它是坎&#xff0c;不是因为PCL本身多难&#xff0c;而是这套组合里每一步都藏着细节&#xff1a;预编译包和VS版本必须匹配、第三方依赖多到记不住、环境变量漏一个就全局崩盘。这篇…

作者头像 李华
网站建设 2026/9/15 19:57:48

AI自动生成单元测试断言:覆盖率提升实战

1. 项目背景与核心思路去年在给团队做单元测试覆盖率优化时&#xff0c;我发现一个有趣的现象&#xff1a;80%的测试漏洞都集中在少数几类断言逻辑上。这让我萌生了一个想法——如果能让AI学习这些历史Bug模式&#xff0c;是不是就能自动生成更健壮的断言代码&#xff1f;经过三…

作者头像 李华