这次故障不是 WordPress 本身也不是 PHP-FPM 参数导致的。真正的根因是两段链路问题叠加:
- 容器环回(loopback/REST)请求走了不稳定链路:PHP 容器里请求
https://bubaigei.com/wp-json/超时,导致后台(尤其编辑器/健康检查)加载卡顿,EdgeOne 会在源站久不响应时返回 524。 - Docker 容器出网被 iptables FORWARD 默认策略 DROP 掐死:宿主机 curl 外网正常,但 PHP 容器 curl
api.wordpress.org超时,导致插件/主题目录加载报错。把 FORWARD 相关规则补齐后恢复。
最终修复:
- 把容器内访问站点域名的解析指向 host-gateway(172.17.0.1),让 WordPress 自请求不绕边缘/公网回环。
- 修复并持久化 iptables FORWARD 规则,恢复 Docker bridge 网络出网。
背景环境 🧩
- VPS:2 核 4G,Debian
- 面板:1Panel
- 架构:Docker 容器化的 OpenResty + PHP-FPM + MariaDB + Redis
- 站点:3 个 WordPress(准备上第 4 个)
- PHP:8.4.x + OPcache(已启用)
- 缓存:WP Super Cache + Redis Object Cache
- 国内站点接入:Tencent EdgeOne(非 Cloudflare)
现象与影响 🔥
现象 1:后台“转圈几秒”,严重时 524
- 前台秒开(静态/页面缓存命中)
- 后台打开任意页面都要等,偶发直接超时(EdgeOne 524)
现象 2:插件/主题安装页报错
- “发生了预料之外的错误…”
- 站点健康提示:无法与 WordPress.org 通信、REST API/环回请求失败(超时)
排查过程(按时间线复盘)🕵️♂️
1)先从 EdgeOne 缓存模板入手:发现“模板不等于可用”
EdgeOne 的 WordPress 缓存模板存在两个典型坑:
- 规则里只提供
URL path = 等于,没有“前缀/包含/正则”时,/wp-admin/并不能覆盖/wp-admin/*.php。 - 兜底写法(例如把“全站”写成
URL path = /.*)如果仍是“等于”,就等于没写。
采取的缓存策略(最终稳定版)
EdgeOne 只缓存静态资源,其他一律不缓存:
- IF:静态后缀(js/css/jpg/png/webp/svg/woff2…)→ TTL 7 天
- ELSE:不缓存
这能避免 HTML/登录态/REST 被边缘缓存误伤,也让“问题归因”更干净。
注:这一步解决的是“缓存误伤/不可控缓存”,但不是最终根因。
2)关键证据:PHP 容器里访问自己站点 REST(wp-json)超时
在宿主机执行:
docker exec -it PHP8 sh -lc 'curl -I -m 10 https://bubaigei.com/wp-json/ || true'结果:curl: (28) Connection timed out after 10000 milliseconds
这条证据直接说明:后台慢不是浏览器/边缘的问题,是源站(容器)自己发 HTTP 请求就卡住了。
为什么会影响文章编辑页?
- WordPress 后台(特别是 Gutenberg 编辑器)大量依赖 REST API。
- REST/环回慢 → 任何后台页面都可能“转几秒”。
3)第一次误导:把域名映射到“公网 IP”在容器里仍超时
尝试在 compose 里加:
extra_hosts:
- "bubaigei.com:139.155.110.8"现象:容器 getent hosts 已指向公网 IP,但 curl https://bubaigei.com/wp-json/ 仍超时。
原因:容器访问宿主机公网 IP 常会遇到 NAT 回环/发夹(hairpin NAT)问题,宿主机自己能通但容器不一定能回环成功。
4)关键修复:改用 host-gateway(172.17.0.1)
把 compose 改为:
extra_hosts:
- "bubaigei.com:host-gateway"
- "d4.bubaigei.com:host-gateway"重建后验证:
docker exec -it PHP8 sh -lc 'getent hosts bubaigei.com; curl -I -m 10 https://bubaigei.com/wp-json/ || true'输出:解析到 172.17.0.1,并且 HTTP/2 200 秒回 ✅
这一步基本解决了:
- WordPress 后台的 REST/环回超时
- 后台页面普遍“转圈几秒”的核心卡点
- EdgeOne 524 的主要诱因(源站迟迟不响应)
5)第二个根因:插件/主题目录仍报错 —— 宿主机能上网,容器不能上网
宿主机:
curl -I -m 10 https://api.wordpress.org/plugins/info/1.2/ || true
# 200 OK容器(PHP8):
docker exec -it PHP8 sh -lc 'curl -sS -m 10 -o /dev/null -w "HTTP=%{http_code}\n" https://api.wordpress.org/plugins/info/1.2/ || echo FAIL'
# 超时 FAIL结论:不是 WordPress.org 被墙(宿主机能通),而是 Docker bridge 网络出网被拦。
6)快速定位:iptables FORWARD 默认 DROP
查看:
iptables -S FORWARD | head -n 20结果:-P FORWARD DROP
这会导致:宿主机自己出网没问题,但容器转发/NAT 出网挂掉。
最终修复(可复制的操作清单)🧰
A. 让容器内的“站点自请求”走 host-gateway(解决 REST/环回卡顿)
在 PHP8 的 compose 里:
extra_hosts:
- "bubaigei.com:host-gateway"
- "d4.bubaigei.com:host-gateway"重建:
docker compose up -d --force-recreate验证:
docker exec -it PHP8 sh -lc 'curl -I -m 10 https://bubaigei.com/wp-json/ || true'B. 修复 Docker 出网(解决插件/主题目录、更新检查)
1)开启内核转发
sysctl -w net.ipv4.ip_forward=12)在 FORWARD 链插入三条放行规则(更稳,比全局 ACCEPT 更克制)
iptables -I FORWARD 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -I FORWARD 2 -i docker0 -o eth0 -j ACCEPT
iptables -I FORWARD 3 -i eth0 -o docker0 -j ACCEPT如果默认网卡不是
eth0,用ip route | grep default看dev是什么再替换。
3)验证容器出网
docker exec -it PHP8 sh -lc 'curl -I -m 10 https://api.wordpress.org/plugins/info/1.2/ || true'C. 持久化(否则重启会复发)💾
1)保存 IPv4 规则
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v42)安装并启用持久化服务
apt-get update
apt-get install -y iptables-persistent
netfilter-persistent save3)(可选)生成空的 IPv6 规则文件,避免启动报错
ip6tables-save > /etc/iptables/rules.v6
systemctl restart netfilter-persistent验收标准 ✅
1)容器内 REST 自请求正常
docker exec -it PHP8 sh -lc 'curl -I -m 10 https://bubaigei.com/wp-json/ || true'
# 2002)容器内能访问 WordPress.org API
docker exec -it PHP8 sh -lc 'curl -I -m 10 https://api.wordpress.org/plugins/info/1.2/ || true'
# 2003)后台体验恢复
- 插件 / 主题安装页可正常加载
- 站点健康不再报 REST/环回/WordPress.org 通信超时
- EdgeOne 524 显著减少或消失
经验教训(以后少踩坑)🧠
- “前台秒开”并不代表源站健康:前台缓存掩盖了后台/REST 的真实延迟。
- 先在容器里测:WordPress 的 cURL/HTTP 请求是在 PHP 容器里发的,不要只看宿主机网络。
- EdgeOne/边缘 524 是结果,不是原因:它只是告诉你“源站没及时响应”。要去找“源站为何不响应”。
- Docker 出网问题第一眼看 FORWARD:
-P FORWARD DROP是典型雷点。 - 域名映射别直接指公网 IP:容器访问宿主机公网 IP 可能遇到 hairpin NAT;
host-gateway更稳。
附:一份“以后遇到后台慢/524”快速检查表 ✅
- 容器内
curl -I -m 10 https://站点/wp-json/是否超时? - 容器内
curl -I -m 10 https://api.wordpress.org/plugins/info/1.2/是否超时? -
iptables -S FORWARD是否为DROP? - 是否已持久化
/etc/iptables/rules.v4并启用netfilter-persistent? - EdgeOne 是否仅缓存静态,避免后台/REST 被缓存?
- PHP-FPM
pm.max_children是否过低导致后台排队?(2C4G 多站一般 8 起步更舒服)
备注(可选优化方向)🛠️
- WP-Cron 改系统 cron,减少后台随机卡顿
- 定期检查 slowlog,定位慢插件/慢查询
- EdgeOne 单独给后台域名直连源站(admin 子域名不走边缘),体验更稳但配置略多
