使用 1Panel 和内网穿透部署 WordPress 实例要点备忘
今天为了测试一个程序,需要同时搭建两个 WordPress 实例,特别是依赖于部分非缺省的 PHP 扩展,1Panel 应用商店里的 WordPress 对应的 PHP 环境相对固化,难以满足个性化需求,因此最终选择了手动创建网站实例,然后通过容器化方式单独挂载运行 PHP 和 MySQL。这样做的最大好处是自由度较高,可自由选择 PHP 或 MySQL 版本,如对 PHP 扩展有特定要求,也方便安装维护。
我的服务器在内网,通过 FRP 内网穿透方式实现公网访问,且两个实例均使用了 Redis 缓存。
今天在部署过程中踩了不少坑,为方便后续查阅,避免反复通过 AI 寻求解决办法,因此把几个核心要点记录下来。
一、frp 内网穿透下的端口暴露与 Nginx 配置
因为使用了 frp 进行内网穿透,外部流量经过穿透到达本地的 Nginx (具体为:OpenResty)时,会发生端口号暴露。例如访问 domain.com/wp-admin (最后没有以 / 结尾)时,会默认跳转为 domain.com:8585/wp-admin/ (出现的端口号 8585 即本地搭建时网站实例的端口号),导致无法访问。
1、修改本地 1Panel 的 Nginx 配置
为解决这个问题,需修改本地网站的 Nginx 配置文件,关闭绝对重定向和端口重定向:
# 在 Nginx 站点的 server 块中添加或修改以下配置(找个位置靠前些的)
server {
# ... 其他配置 ...
# 避免 Nginx 在做目录重定向时带上非标准端口号
absolute_redirect off; # 会让 Nginx 直接返回相对路径的重定向指令,比如让浏览器直接跳到 /wp-admin/,从而完美避开域名和端口的拼接错误。
port_in_redirect off;
# ... 其他配置 ...
}2、检查反向代理的 Header 头(可选但推荐)
为了防止 WordPress 内部的其他链接也错误识别端口,需确保 frp 服务端在反向代理时,把真实情况传递给了内网。
检查外网服务器反向代理配置( location / { ... } 内部),确保包含以下 Header 参数:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header X-Forwarded-Host $host;这一步的作用是强制要求内网的 1Panel :“外面的访客是用 443 端口访问的,生成任何链接时都别把 8585 露出来”。
二、解决混合资源(Mixed Content)与 403 报错
目前我采取的是通过 FRP 的 HTTP 协议实现域名访问内网服务,还需要在 FRP 服务器中通过 nginx 的反向代理,实现去端口化以及 SSL 协议。
但 frp 反向代理( 外网 HTTPS -> frp -> 内网 1Panel Nginx -> Docker PHP )的架构下,代理服务器传递的 HTTPS 协议头( X-Forwarded-Proto )容易丢失,导致以下两个问题:
- 后台无限重定向:WordPress 发现后台需要 HTTPS,试图重定向到 HTTPS,但重新请求进来又被识别为 HTTP,从而陷入死循环,提示重定向次数过多。
- 前台 Mixed Content 报错:网页加载的静态资源(SVG、CSS、JS)全部被强制输出为 http:// 开头的链接,被浏览器拦截,导致页面样式错乱及控制台报错。
解决方法很简单,即通过 WordPress 的配置文件 wp-config.php ,在 /* That's all, stop editing! Happy publishing. */ 这一行之前,强制开启 HTTPS 识别,并固定站点 URL:
// 强制开启 HTTPS,无视反向代理的头部丢失问题
$_SERVER['HTTPS'] = 'on';
define('FORCE_SSL_ADMIN', true);
// 强制定义主页和站点 URL,防止数据库中记录的 http 协议引发错误
define('WP_HOME', 'https://domain.com');
define('WP_SITEURL', 'https://domain.com');此外,为了让 frp 后的应用更好地感知真实请求,建议在 frp 服务端的 Nginx 反向代理配置中,确保传递了正确的请求头。在 Nginx 的 location 块中添加(可选但推荐):
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;三、解除 PHP 上传文件尺寸及等待时间限制
上传文件时,因文件大小超出默认 PHP 最大允许文件上传尺寸,造成上传失败,修改 php.ini 即可,通过 1Panel --> 网站 --> 运行环境 ,提供了可视化修改。
主要修改以下参数:
max_execution_time:默认通常是 30,改大一点,比如 300 或 600。
max_input_time:也改成 300 左右。
upload_max_filesize 和 post_max_size:确保这两个值大于导入文件的大小(比如改成 50M 或 100M)。
四、Redis 容器化部署与多实例隔离
因需要,两个 WordPress 实例均需开启 Redis 缓存,使用 Redis Object Cache 缓存插件来连接 Redis 服务。
我的 Redis 服务是通过 1Panel 应用商店直接安装,即容器化部署。总的来说,WordPress 所处的环境如下:
- WordPress 本地主机中部署
- PHP 容器化部署
- Redis 容器化部署
- Openresty 容器化部署
安装 Redis Object Cache 插件,启用时直接报错:Redis 无法访问: Connection refused [tcp://127.0.0.1:6379]
默认的 Redis 服务地址为 127.0.0.1 ,这在传统环境下没问题。但在 Docker 容器化部署中,如果 PHP 填写 127.0.0.1 ,实际上是在尝试连接 PHP 容器内部的地址,自然找不到外部的 Redis 容器!
把连接地址改为 Redis 的容器名,即可让 PHP 正常与 Redis 容器通信。详细操作如下,同时也顺带解决了多实例 WordPress 共用一个 Redis 容器的隔离问题。
1、修改 object-cache.php 配置文件
文件位置在:/wp-content/plugins/redis-cache/includes/object-cache.php
找到 build_parameters() 函数,默认配置如下:
protected function build_parameters() {
$parameters = [
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'database' => 0,
'timeout' => 1,
'read_timeout' => 1,
'retry_interval' => null,
'persistent' => false,
];将其修改为:
protected function build_parameters() {
$parameters = [
'scheme' => 'tcp',
'host' => '1Panel-redis-kpTr', // 将 127.0.0.1 修改为 Docker 的容器名
'port' => 6379,
'database' => 0, // 注意这里:多网站隔离时,第一个网站用 0,第二个网站改用 1
'password' => 'password', // 改为 Redis 的密码
'timeout' => 1,
'read_timeout' => 1,
'retry_interval' => null,
'persistent' => false,
];小提示:Redis 默认自带了 16 个逻辑数据库(编号从 0 到 15)。可以通过修改这里的 ‘database’ => 0 为其他数字,来区分不同网站的不同 Redis 数据库,完全不用重复创建 Redis 容器。
2、修改 wp-config.php 配置文件
在最下方添加如下代码:
/** Redis Object Cache */
define( 'WP_REDIS_HOST', '1Panel-redis-kpTr' ); // Redis 容器名
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_PASSWORD', 'password' ); // Redis设置了密码时填写
保存上述文件后,回到 WordPress 控制台的插件界面刷新,点击开启即可。
其他:如何清除 Redis 的指定数据库
1. 登录 Redis CLI:
在终端中输入以下命令进入 Redis 的交互模式,并使用密码进行身份验证:
redis-cli按下回车后,接着输入授权命令:
AUTH password如果密码正确,系统会返回 OK。
2. 切换到 0 号数据库:
Redis 默认登录后就是 0 号数据库,但为了绝对安全,手动指定一下:
SELECT 0系统会返回 OK。
3. 清空当前数据库
在确认当前是 0 号数据库后,输入以下命令清空它:
FLUSHDB系统会返回 OK,此时 0 号数据库的数据已经被彻底清空。
在这个界面下,绝对不要输入
FLUSHALL命令。FLUSHDB只清空当前所在的库,而FLUSHALL会把0到15号库全部干掉。
4. 验证并退出
输入以下命令查看当前数据库的键值数量,确认是否已经清零:
DBSIZE如果返回 (integer) 0,说明清理成功。
最后,输入 exit 退出 Redis 交互模式,再关闭终端窗口即可。
© 转载需附带本文链接,依据 CC BY-NC-SA 4.0 发布。