
两个域名各司其职:
|
域名 |
服务 |
谁能访问 |
|
|
WordPress 后台 + REST API |
只有你(管理端) |
|
|
Nuxt 前台 + 构建器 |
所有人(访客) |
★ 不要把 WordPress 后台暴露在对外的前端域名上。 前端只通过
/api/mb/*代理访问后端,访客看不到 WP 的存在。
1. 环境准备
|
组件 |
版本 |
说明 |
|
宝塔面板 |
7.x / 8.x |
Linux 面板 |
|
Nginx |
1.22+ |
反向代理 |
|
PHP |
8.2 |
WordPress + MyBuilder |
|
MySQL |
5.7 / 8.0 |
WordPress 数据库 |
|
Node.js |
v24.20.0 |
Nuxt 3 SSR |
|
WordPress |
6.x |
后台 |
磁盘:至少 2 GB 空闲。Nuxt 的 node_modules ≈ 170 MB,.output ≈ 4 MB。
2. 后端:WordPress + MyBuilder
2.1 建站
宝塔 → 网站 → 添加站点:
|
字段 |
值 |
|
域名 |
|
|
根目录 |
|
|
PHP 版本 |
PHP-82 |
|
数据库 |
MySQL(名字建议 |
2.2 装 MyBuilder 插件
上传 mybuilder-1.0.1.zip → 插件 → 安装 → 启用。
启用后会自动做这些事:
- 注册
mybuilderCPT(页面布局)
- 注册
core.*模块(40+ 种)
- 预置 18 个页面(home / posts / community / shop / about / faq / agreement …)
- 预置全站侧栏(
core.siteNav竖排主菜单)
- 激活钩子里自动写
regions(页头/侧栏/页脚)
★ 预置只在「页面不存在」时补,不会覆盖你改过的。
2.3 nginx 伪静态(★ 必配,否则全站 404)
宝塔 → 网站 → gou.mybuder.cn → 设置 → 伪静态:
★ WordPress 的「固定链接」设置只写
.htaccess,nginx 不读它。 必须在这里配try_files,否则/wp-json/...全部 404(前台登录会报「请求失败」)。★ 不要在
server {}里手写if (!-e $request_filename) { rewrite ... }—— 它会被enable-php-82.conf里的location ~ \.php$抢先匹配而失效。
3. 后端:站点关键配置
3.1 固定链接(★ 必改)
设置 → 固定链接 → 选 文章名 → 保存。
3.2 站点地址
设置 → 常规:
|
字段 |
值 |
|
WordPress 地址(URL) |
|
|
站点地址(URL) |
|
★ 两个都要是
https://。写http://会导致 cookie 失效(登录后又跳回登录页)。
3.3 缓存清除密钥
MyBuilder → 机器凭证 → 记下「缓存密钥」。
前端 .env 的 NUXT_MB_CACHE_KEY 必须与它完全一致。
3.4 前端地址
MyBuilder → 全局基础数据 → 「前端地址(Nuxt SSR)」:
★ 不带
/builder、不带/。填错会静默失效 4 个功能(见坑 16)。
3.5 菜单导航(左侧竖排菜单的数据源)
站点设置 → 页头页脚 → 菜单导航。
菜单项字段:
|
字段 |
说明 |
|
名称 |
显示文字 |
|
链接 |
|
|
图标 |
|
|
徽章 |
如「优质」「免费」,只在侧栏显示 |
|
可见角色 |
留空 = 所有人 |
3.6 页脚
站点设置 → 页头页脚 → 页脚:
- 标语:两行(第一行大字,第二行灰色小字)
- 版权信息:留空(模板已输出「站名 © 年份」)
- 页脚链接:横排一排小字,最多 5 条
★ 「链接列」是旧版概念,现在是「页脚链接」单组横排。留空则用前端内置的常用入口。
4. 前端:传代码 + 构建
4.1 传包
上传 mybuilder-frontend-1.0.1.zip 到 /www/wwwroot/,解压:
★ zip 顶层已有
mybuilder-frontend/,所以解压到/www/wwwroot/。 解压到/www/wwwroot/mybuilder-frontend/会多套一层 →Could not read package.json。
4.2 一键部署(推荐)
deploy.sh 依次完成:
4.3 手工部署(想看每一步时)
4.4 .env 生产配置
|
变量 |
值 |
填错的后果 |
|
|
|
前端读不到数据 |
|
|
|
GraphQL 查询失败 |
|
|
|
canonical 指向错域名,SEO 权重全丢 |
|
|
留空 |
权威来源是 WP 后台,写死会盖掉后台设置 |
|
|
与 WP |
后台保存后前台不刷新 |
5. 前端:宝塔 Node 项目 + 反代 + SSL
5.1 宝塔 Node 项目
网站 → 添加 Node 项目:
|
字段 |
值 |
|
项目目录 |
|
|
项目名称 |
|
|
启动选项 |
自定义启动命令 |
|
自定义启动命令 |
|
|
Node 版本 |
|
|
包管理器 |
|
|
运行用户 |
|
|
项目端口 |
|
保存 → 点「启动」。
★ 宝塔的「项目端口」不注入
PORT环境变量(只是记录 + 健康检查)。 端口已写死在server-start.mjs(默认 3001),所以启动命令只填npm start。
5.2 反向代理
网站 → mybuder.cn → 设置 → 反向代理 → 添加:
|
字段 |
值 |
|
目标 URL |
|
|
发送域名 |
|
配置文件里必须补(宝塔默认不给):
5.3 SSL
SSL → 申请证书(Let’s Encrypt)→ 开启「强制 HTTPS」。
6. 前后端联调:4 个必配项
装完之后这 4 处必须对上,否则会出现「能打开但没数据」「保存了不生效」这类怪问题:
|
# |
位置 |
填什么 |
不对的后果 |
|
1 |
WP「设置 → 常规」两个 URL |
|
登录跳转错域名 |
|
2 |
WP「MyBuilder → 全局基础数据 → 前端地址」 |
|
构建器跳错、缓存不清、密码链接错 |
|
3 |
WP「机器凭证 → 缓存密钥」↔ 前端 |
两边完全一致 |
后台保存后前台 60 秒才更新 |
|
4 |
WP「页头页脚 → 菜单导航」 |
菜单项 |
左侧竖排菜单空白 |
7. 完整验证清单
7.1 后端
7.2 前端
7.3 功能核对
|
项 |
怎么验 |
|
多页 |
|
|
构建器 |
|
|
保存生效 |
拖模块保存 → 立刻刷新首页看变化(不是等 60 秒) |
|
404 |
访问不存在路径 → 状态码 404 但页面有内容(保留导航) |
|
侧栏 |
左侧竖排菜单(图标 + 文字 + 徽章) |
|
页脚 |
左标语 + 右一排小字链接 + 底版权行 |
8. 20 个真实踩过的坑
后端侧
① 固定链接选了「文章名」但前台还是 404
根因:nginx 没配 try_files(WordPress 只写 .htaccess,nginx 不读)。 解法:见 §2.3。
② 配了 if (!-e $request_filename) 但还是 404
根因:enable-php-82.conf 里的 location ~ \.php$ 抢先匹配,server 级的 rewrite 根本没机会跑。 解法:改用 location / { try_files ... },删掉手写的 if。
③ 登录后跳到另一个域名
根因:siteurl / home 被设成了别的域名。siteurl 是绝对地址,登录必然按它跳转。 解法:设置 → 常规改成自己的域名,改完登出重新登录(旧 cookie 按旧域名签的)。
④ 两套 WordPress 共用一台服务器,文章 ID 一模一样
根因:建站时用了宝塔「复制站点」,数据库是克隆的 —— siteurl 也一起被克隆了。 判据:/wp-json/ 路由数不同(140 vs 243)说明插件不同;文章 ID 相同说明数据库同源。 解法:改回各自的 siteurl;wp-config.php 里若定义了 WP_HOME/WP_SITEURL 常量优先于数据库,两个都要改。
⑤ 页面全空白(HTTP 200 但 0 字节)
根因:PHP fatal error,但 WP_DEBUG = false 把错误藏起来了。 解法(临时打开日志,不给访客看):
然后 tail -30 /www/wwwroot/<目录>/wp-content/debug.log。
⑥ 改了 siteurl 后不生效
根因:wp-config.php 里 define('WP_HOME', ...) 优先级高于数据库。 解法:grep -E "WP_HOME|WP_SITEURL" /www/wwwroot/*/wp-config.php,有就一起改。
前端侧
⑦ 宝塔终端里 node 不在 PATH
根因:宝塔的 Node 版本管理器只往它自己启动的进程注入 PATH。 解法:export PATH="/www/server/nodejs/v24.20.0/bin:$PATH"
⑧ Nuxt 遥测询问挂死部署
根因:nuxt prepare(postinstall 触发)首次运行会交互式询问。 解法:nuxt.config.ts 里 telemetry: false + export NUXT_TELEMETRY_DISABLED=1。
⑨ zip 解压多套一层目录
症状:Could not read package.json 解法:解压到 /www/wwwroot/(顶层已有 mybuilder-frontend/)。
⑩ 依赖没装 / 装的是旧版
解法:用 npm install 而不是 npm ci(ci 要求 lock 完全同步,服务器的 lock 可能是旧的)。 首次安装 3-5 分钟。
⑪ 构建没做就启动
症状:Cannot find module '.output/server/index.mjs' 解法:宝塔只管启动不负责构建,必须先 npm run build。
⑫ 端口回落默认值 3000
症状:EADDRINUSE: port 3000 根因:宝塔的「项目端口」不注入 PORT 环境变量。Nitro 读 NITRO_PORT || PORT || 3000。 解法:端口写进 server-start.mjs。
⑬ 宝塔不支持 VAR=value 命令
症状:failed to run command 'NITRO_PORT=3001' 解法:把变量写进启动脚本,不在命令行拼。
⑭ 生产启动依赖 devDependency
症状:cross-env: command not found 根因:cross-env 在 devDependencies,NODE_ENV=production 时被跳过。 解法:server-start.mjs 是零依赖的纯 node。
⑮ ★ .env 不生效(今天排查最久的一个)
症状:[MB] 已从 .env 加载 0 个环境变量 / 后端 REST: (未设置)
两个原因:
a) Nuxt 的 runtimeConfig 是「构建时内联」的 —— 构建时没设对,产物里就固化了 http://127.0.0.1/graphql,运行时改 .env 无效,必须重新构建:
b) 启动器判断逻辑写错 —— Nuxt 构建时会把 .env 的值注入进程环境变量, 启动时再读同一文件,process.env[key] === undefined 全部不成立。 必须无条件覆盖。
★★★ 这个坑就藏在我自己写的
deploy.sh里:它生成了.env、 还「打印了正确的值」给人一切正常的错觉,但没把内容加载进 shell 就构建。 已修:构建前set -a; . ./.env; set +a,且NUXT_MYBUILDER_REST为空就exit 1。
⑯ public.* 配置要用另一个变量名
|
runtimeConfig 键 |
运行时覆盖用 |
|
|
|
|
|
|
症状很有欺骗性:后端 REST 覆盖成功,但 canonical 还是旧值。
⑰ canonical 带 :443
根因:nginx 的 Host 带了端口,Nuxt 不知道自己是 https。 解法:补 proxy_set_header X-Forwarded-Proto $scheme;
⑱ 「打开前台构建器」跳到后端域名
根因:按钮硬编码了 home_url(),「前端地址」输入框形同虚设。 解法:读 mb_frontend_origin 配置值;并给它加保存校验(协议/路径/空格)。
⑲ 前端 502「请求失败,请稍后再试」
排查顺序(别跳步):
⑳ 页面改了没变化 / 看到的是旧版
先判断是服务端还是浏览器:
- 返回 0 → 服务端就是旧的(重新构建 + 重启)
- 返回 >0 → 服务端是新的,你看到的是浏览器缓存(Ctrl+Shift+R / 无痕窗口)
★ 「秒闪一下又变回旧版」= Nuxt SSR 先渲染新版,浏览器再用本地缓存的旧 HTML 覆盖。
9. 日常运维
更新代码
★ 构建后一定要重启 —— 只构建不重启,跑的还是旧代码。 ★ 改
.env也要重启。 ★ 用宝塔 Node 项目的「重启」按钮更稳(PM2 托管,崩溃自动重启 + 开机自启)。
备份
10. 故障速查表
|
现象 |
根因 |
去哪看 |
|
|
终端 PATH 没 node |
坑 ⑦ |
|
遥测询问卡死 |
Nuxt 交互询问 |
坑 ⑧ |
|
|
解压多套一层 |
坑 ⑨ |
|
|
依赖没装 |
坑 ⑩ |
|
|
没构建 |
坑 ⑪ |
|
|
端口回落默认值 |
坑 ⑫ |
|
|
宝塔不支持该语法 |
坑 ⑬ |
|
|
依赖 devDep |
坑 ⑭ |
|
「已从 .env 加载 0 个」 |
runtimeConfig 构建时内联 |
坑 ⑮ |
|
后端对了但 canonical 错 |
|
坑 ⑯ |
|
canonical 带 |
缺 |
坑 ⑰ |
|
构建器跳到后端域名 |
硬编码 |
坑 ⑱ |
|
前端 502「请求失败」 |
查 ⑲ 三步 |
坑 ⑲ |
|
首页 0 字节 |
PHP fatal,DEBUG 关着 |
坑 ⑤ |
|
|
nginx 缺 |
坑 ① |
|
登录跳错域名 |
|
坑 ③ |
|
改 siteurl 不生效 |
wp-config 常量优先 |
坑 ⑥ |
|
页面改了没变化 |
浏览器缓存 |
坑 ⑳ |
|
|
Node 版本低 |
装 22.12+ / 20.19+ |
|
|
属主是 root |
|
|
npm 卡住 |
网络 |
|
|
磁盘满 |
node_modules 累积 |
|
附:项目结构
不含 node_modules/ .nuxt/ .output/ .env —— 都在服务器上生成。
附:MyBuilder 后台菜单速查
|
菜单 |
作用 |
|
MyBuilder(首页) |
概览 + 「打开前台构建器」+ 前端地址 |
|
全局基础数据 |
授权中心、隔离模式、缓存密钥 |
|
机器凭证 |
API Secret、机器凭证列表 |
|
外观主题 |
主题切换 |
|
页面布局 |
18 个预置页的管理与「恢复预置版式」 |
★ 1.0.1 起没有「全站区域」后台页 —— 侧栏靠激活时自动写入,零操作。
