无头 WordPress 部署:DNS、SSL 和 AI
Tech
AI
headless CMS
WordPress
Next.js

无头 WordPress 部署:DNS、SSL 和 AI

真正的无头 WordPress 部署可能会破坏 DNS、SSL、图片和表单。下面是我在生产环境中如何修复的。

Uygar DuzgunUUygar Duzgun
Mar 27, 2026
Updated 2026年4月4日
8 min read

这是我无头 WordPress 迁移系列的第 2 部分。无头 WordPress 部署(Headless WordPress deployment)真正的问题才开始出现,因为 DNS、SSL、图片、表单和重定向会以不同方式全部失效。在第 1 部分中,我用 Claude Code、Stitch MCP 和 Next.js 在一天内重建了前端。在本文中,我会展示我遇到的部署问题、我是如何修复的,以及为什么 AI 仍然需要人的判断。

大多数人都不谈的无头 WordPress 部署问题

搭建前端是容易的部分。以我的经验,无头 WordPress 部署一旦把一个网站拆成两个系统就会变难:Vercel 负责前端,WordPress 负责后端。你不再只有一个简单的技术栈。你会同时面对 DNS、证书、媒体 URL、REST 端点和管理访问,它们彼此之间在不同方向上拉扯。

当 `optagonen.se` 迁移到 Vercel 后,所有原本会请求到 WordPress 的流量都开始落到新的前端上。一次性就把 GraphQL、上传、Contact Form 7 和后台访问都弄坏了。如果你计划自己的 无头 WordPress 部署,在切换 DNS 之前你就需要为这些断点做好设计。

我是在真实的生产迁移中验证的,而不是在沙盒里。结论很明确:代码完成得很快,但基础设施花了时间。

为无头 WordPress 部署拆分 DNS

最干净的修复方式是给 WordPress 单独一个子域:`wp.optagonen.se`。这样在不强迫我把所有内容都通过一个源来反向代理的情况下,把前端和后端分离开来。排查 SSL 和媒体分发问题时,这种架构也更容易理解。

DomainPoints toPurpose
---------
`optagonen.se`VercelNext.js 前端
`wp.optagonen.se`Origin serverWordPress 后端

我在 Hestia 中把 `wp.optagonen.se` 添加为别名,把 DNS A 记录指向源服务器的 IP,并更新了前端环境变量:

`WP_URL=https://wp.optagonen.se`
`CF7_FORM_ID=8`
`WP_APP_PASSWORD=...`

纸面上这部分很简单。实际中,无头 WordPress 部署暴露出连锁反应。每一个假设旧域名仍然有效的系统,都需要一个新的目标。

无头 WordPress 部署与 SSL 证书失败

首先坏掉的是 SSL。旧的 Let's Encrypt 证书只覆盖 `optagonen.se` 和 `www.optagonen.se`,所以 `https://wp.optagonen.se` 会立刻失败。这是预期行为。Let's Encrypt 会按主机名验证域名所有权,如果证书不匹配,浏览器就会拒绝连接。

Hestia 的内置续期失败了,因为它仍然试图通过 HTTP-01 验证主域名,但主域名现在指向了 Vercel。Certbot 失败的原因不同:Hestia 拦截了 ACME challenge,并返回了它自己的指纹,而不是 Certbot 的。AI 无法从第一性原理推断出这种冲突。你需要知道面板会如何表现。

我通过临时把 Hestia 的 ACME challenge 配置从 nginx include 路径中移出来修复:只为 `wp.optagonen.se` 签发证书,然后把续期后的文件再复制回 Hestia 的 SSL 目录。我也添加了续期钩子,让流程保持自动化。

为了建立信任,我参考了 Let's EncryptCertbot 的官方文档。这帮助我在再次动生产环境之前确认了 ACME 流程。

为什么无头 WordPress 部署拒绝了子域

SSL 一旦工作起来,WordPress 仍然不接受新的主机。它没有返回 GraphQL 数据,而是重定向到了 `/wp-signup.php`。这让我意识到 WordPress 不喜欢传入的 host header。

修复只需要一条 nginx 指令:

`proxy_set_header Host optagonen.se;`

这一行让 WordPress 表现得就像请求仍然来自主域名,而浏览器仍停留在 `wp.optagonen.se`。在 无头 WordPress 部署中,这种 host 规范化比人们想象得更重要。WordPress 对站点 URL 非常有主见。

我在其他迁移里也见过同类问题:前端能工作、后端有响应,然后由于某个 host header 不匹配,session 流程会在不明显的情况下悄悄断掉。

无头 WordPress 部署后图片坏了

部署之后,每张图片都返回 502 错误。这是因为 WordPress 的媒体 URL 仍然指向 `/wp-content/uploads/...`,而这些路径现在会在 Vercel 上解析,而不是在源服务器上解析。在我的设置里,问题来自两个地方:静态文件里的硬编码 URL,以及 WPGraphQL 返回的动态 URL。

我先修复硬编码的 URL。我把所有 `https://optagonen.se/wp-content/uploads/` 引用替换为 `https://wp.optagonen.se/wp-content/uploads/`,覆盖了六个文件中的大约 70 个图片路径。

然后我用 Next.js rewrite 修复动态 GraphQL URL:

`/wp-content/uploads/:path*` → `https://wp.optagonen.se/wp-content/uploads/:path*`

这样前端保持干净,也避免在 WordPress 内部重写媒体数据。它还让 无头 WordPress 部署更易维护:浏览器仍然请求相同的路径,而服务器负责代理转发。

Recommended reading

如果你想更深入了解这种系统设计,我建议阅读我这篇 AI 驱动的 WordPress 迁移工作流 以及我的 多代理内容流水线。这些文章展示了我如何围绕自动化来组织基础设施和内容系统。

联系表单、ID 和最后一次部署陷阱

Contact Form 7 起初看起来没问题,但表单停止工作是因为前端里的 ID 写错了。默认表单 ID 是 `1`,但 WordPress 里的真实表单是 `8`。通过一次快速的 API 检查确认了这一点。

这是个小修复,但很关键。在 无头 WordPress 部署中,一个错误的 ID 就可能让一个本来可用的表单看起来像是坏了,即使后端是健康的。我设置了 `CF7_FORM_ID=8`,表单立刻恢复上线。

这也是为什么我总是手动测试完整流程:

从线上前端提交表单。
检查网络请求。
在 WordPress 中确认响应。
验证数据是否到达收件箱或 CRM。

这个顺序比只靠日志猜测能更快捕捉问题。

AI 帮了什么,又漏了什么

Claude Code 帮我提速了,但它并没有替代理解。它很擅长处理重复性的部分:搜索配置文件、生成 nginx 片段、协助 certbot 命令、批量替换图片 URL。它还把错误链条保存在内存里,这在一次修复又引发另一个问题时节省了时间。

不过,AI 无法决定完整架构。它不知道 Hestia 会拦截 ACME 请求。它不知道什么时候应该用子域而不是反向代理。它也不知道为了避免停机,应该按什么顺序执行。

Recommended reading

这就是 无头 WordPress 部署中 AI 的真正价值:它加速诊断,但你仍然需要理解技术栈的人。我的工作里也遵循同样的原则:我在构建 用于电商的 AI 自动化系统 时,以及在内容流水线工作中也是如此。

部署后的最终架构

修复完成后,技术栈稳定地分成了清晰的两部分:

ComponentLocationPurpose
---------
Next.js 前端Vercel提供页面并处理路由
WordPress + WPGraphQL`wp.optagonen.se`内容 API 与媒体存储
Contact Form 7`wp.optagonen.se`表单处理
图片代理Next.js rewrite 规则把上传路由到源服务器
前端 SSLVercel自动管理
后端 SSLCertbot + 续期钩子自动续期证书

这种结构稳定且易于调试。它也能在保留 WordPress 内部编辑工作流的同时,让前端保持快速。对于 无头 WordPress 部署来说,这种平衡就是目标。

从这次无头 WordPress 部署中学到的经验

下面是我从迁移中得到的结论:

DNS 的变更会比你想象中破坏得更多,尤其是当一个域名现在要同时服务两个系统时。
SSL 通常会最先失败,因为证书验证依赖路由。
服务器面板和外部 ACME 工具可能会冲突,如果它们管理的是同一个域名。
图片 URL 存在的地方比你想象得更多,包括静态文件和 GraphQL 输出。
AI 对调试很有用,但它无法替代基础设施层面的判断。

这些经验来自真实的生产迁移,而不是教程。这也是为什么我现在会把部署所需的时间预算得和搭建一样多。

结论

无头 WordPress 部署并不难,难点不在代码。难在 DNS、SSL、媒体和 host headers 彼此都依赖对方。在这次迁移中,我修复了子域拆分、证书验证、图片分发以及 Contact Form 7,并且我清楚地知道 AI 在哪里能帮上忙、哪里就止步了。

如果你也在计划自己的迁移,先读前端重建的部分,尽早测试证书流程,并在上线前验证每一条媒体路径。然后检查线上站点,确认表单,并确保后端仍然以 WordPress 期望的方式工作。

如果你想要更多实用的部署拆解内容,继续阅读相关帖子,并把它们和你自己的技术栈对比。这是避免你下一次 无头 WordPress 部署犯错的最快方式。

建议的图片替代文本(alt text):

展示 Vercel 与 WordPress 拆分架构的截图,包含前端与后端域名
Hestia 控制面板中为 wp.optagonen.se 配置证书续期
Next.js rewrite 规则:把 WordPress 上传映射到源服务器