正式站上直接改主题、试插件,出事成本最高的往往不是白屏,而是脏数据、误发邮件、支付跑到真网关。预发(Staging)的目标很简单:环境尽量像生产,副作用必须被切断。下面按我实际搭的顺序写------克隆、改 URL、隔离邮件/缓存/支付、回同步注意点。
先定边界:Staging 要像生产,但不能当生产用
我会把「像」和「不能」拆开:
- 要像:PHP/MySQL 大版本接近、主题/插件同一套、permalink 结构一致、Woo 结账路径可走通(测试网关)。
- 不能:真实 SMTP 出去、被搜索引擎收录、和正式站共用同一份对象缓存/CDN 键、支付走 live key、定时任务把生产队列跑一遍。
很多人只做了「复制一份站点」,没有做隔离------这比没 Staging 更危险,因为操作者会默认「反正是测试站」。
三种克隆路径,按场景选
1)主机面板一键 Staging
SiteGround、Cloudways、部分国内面板都有。优点是文件+库一起拆,子域名自动配好。缺点:有的面板不会自动关邮件、不会单独配缓存命名空间,克隆完仍要人工过一遍隔离清单。
适用:中小站、想快跑、能接受面板绑定。
2)Duplicator / All-in-One WP Migration 一类打包
适合跨主机、或正式站在 A、预发在 B。流程大致是:生产打包装包 → 预发空目录解包 → 跑安装器改库连接 → 再做 Search Replace。
注意:超大 uploads 容易超时;Woo 订单量大时优先 WP-CLI/rsync+库导出,别硬塞进浏览器上传。
3)手工:文件 + 数据库
bash
# 示例:rsync 文件(排除缓存与会话)
rsync -avz --delete \
--exclude 'wp-content/cache/' \
--exclude 'wp-content/uploads/wc-logs/' \
user@prod:/var/www/site/ /var/www/staging/
# 导出库(按你环境改库名)
mysqldump -u root -p prod_db --single-transaction > prod.sql
mysql -u root -p staging_db < prod.sql
wp-config.php 里改库名、表前缀(若需要)、以及 WP_HOME / WP_SITEURL(或后面统一 Search Replace)。手工路径可控,但漏一步就容易「预发还指着生产库」。
Search Replace:序列化数据是坑点
WordPress 很多选项、小工具、页面构建器数据是 PHP 序列化 。用编辑器全局替换 https://www.example.com → https://staging.example.com,长度一变字符串就坏,表现为小工具空白、Elementor 布局丢、部分插件设置重置。
可靠做法是 WP-CLI:
bash
wp search-replace 'https://www.example.com' 'https://staging.example.com' \
--all-tables --precise --report-changed-only
干跑可先加 --dry-run。带协议和不带协议、带 www 和不带,各跑一轮更稳。若必须用插件(Better Search Replace 等),选「处理序列化数据」选项,并先备份预发库。
改完立刻核对:
bash
wp option get siteurl
wp option get home
两者都应是预发域名。
隔离副作用:邮件、收录、缓存、支付
这四块是「污染正式站」的主要通道。
邮件:默认拦截
预发上真实 SMTP 一开,密码重置、Woo 订单、表单通知都会打到真实客户邮箱。做法任选其一:
- 装邮件拦截插件(把发出的信落库/落日志,不投递);
- 指向 Mailhog / Mailpit 一类本地捕获;
- 或在
wp-config.php阶段直接让wp_mail空跑(团队有统一 mu-plugin 更好)。
不要把生产 SMTP 账号密码原样留在预发。
收录:robots + noindex 双保险
apache
# 预发站点根目录 robots.txt 示例
User-agent: *
Disallow: /
后台「设置 → 阅读」勾选「建议搜索引擎不索引」。有的 SEO 插件还会单独写 noindex,预发环境打开它。子域名若被外链指过来,双保险比单靠 robots 踏实。
缓存与 CDN:键空间必须分开
对象缓存(Redis/Memcached)若和生产共用实例、又没换 WP_CACHE_KEY_SALT / 前缀,预发清缓存可能把生产键扫掉,或反过来读到脏数据。CDN 同理:预发域名单独源站、单独缓存策略;不要让预发 URL 误进生产的缓存规则。
页面缓存插件在预发可以开(为了测命中),但缓存目录、Redis DB index、CDN zone 都要和生产切开。
支付与 Webhook:一律测试模式
Woo 支付、订阅、发票类插件:切 sandbox / test key。Webhook URL 若仍指向生产域名,测试支付会回调正式站------把预发的 webhook 改到预发 URL,或在网关后台为测试密钥单独配回调。
定时任务(Action Scheduler、cron)也会在预发跑。大站可考虑:
bash
# 预发临时关掉 WP-Cron 触发(改用可控的手动跑)
# wp-config.php
define('DISABLE_WP_CRON', true);
需要测队列时再手动 wp cron event run --due-now。
回同步:只推「确认过的变更」,别整库覆盖
预发验证通过后,常见错误是「把预发整库导回生产」。订单、会员、评论、库存会在预发停留期间继续增长,整库覆盖等于时间回滚。
更稳的做法:
- 生产先做可回滚备份(文件+库,并验包);
- 只同步主题/子主题、指定插件、必要的配置导出;
- 内容类改动用正式编辑流程或迁移工具按文章/产品粒度推;
- 数据库层面优先结构化变更(迁移脚本),避免盲替换。
「预发改完感觉挺好 → 覆盖生产」这种习惯,出事一次就够改。
上线前自检清单(可复制)
-
siteurl/home是预发域名;库名不是生产库 - 邮件已拦截或指向捕获服务;抽测一封表单/订单通知不进真实收件箱
- robots + 阅读设置 noindex;抽查响应头/源码有 noindex 更佳
- Redis/缓存前缀、CDN 与生产隔离;清预发缓存不影响生产
- 支付/订阅为测试模式;webhook 指向预发
- 管理员账号密码与生产不同(克隆后立刻改)
- 插件更新、主题切换、结账主路径各走通一遍
Staging 不是「多一个域名」,而是可重复的隔离协议。克隆只是第一步,Search Replace 和副作用切断才决定它会不会反过来污染正式站。