Discuz! 论坛迁移实战:从多机架构到单机部署完整记录
背景
内部论坛原架构由多台机器组成(Web 服务器 + 文件服务器 + 附件服务器),运行多年后出于运维简化考虑,决定合并为单机部署。同时需要将测试环境验证通过的配置迁移至正式环境。
原架构 vs 新架构
| 对比项 | 原架构(多机) | 新架构(单机) |
|---|---|---|
| Web 服务 | 商业 Web 服务器 + Nginx | Nginx |
| PHP | 7.x(php-fpm) | 7.x(php-fpm) |
| Redis | 远程独立部署 | 本地部署 |
| MySQL | 独立数据库服务器 | 独立数据库服务器(不变) |
| 附件存储 | 网络文件系统(远端挂载) | 本地存储 |
| SSL | 泛域名证书 | 泛域名证书 |
迁移步骤
1. 环境准备
在新服务器上安装基础环境:
– Nginx(较新稳定版)
– PHP 7.x + php-fpm
– Redis
– 可视化面板管理工具(用于可视化管理)
2. 代码同步
从旧 Web 服务器同步论坛代码:
rsync -avz --exclude='data/cache' --exclude='data/sysdata' \
--exclude='data/attachment' --exclude='data/template' \
--exclude='config/config_global.php' \
--exclude='config/config_ucenter.php' \
旧Web服务器IP:%WEB_ROOT%/ %WEB_ROOT%/
3. 附件同步
从旧网络文件服务器同步附件数据:
rsync -avz 旧文件服务器IP:%ATTACHMENT_DIR%/ %WEB_ROOT%/data/attachment/
4. 数据库处理
从旧数据库服务器导出最新数据,导入到目标数据库。有两种方式:
–
方式 A:导出 SQL → 导入到本地 MySQL
–
方式 B:直接修改配置文件指向旧数据库服务器
这里我采用了重新导入正式数据库的方式,确保数据完全一致。
5. 配置文件修改
config/config_global.php
// 数据库配置
$_config['db']['1']['dbhost'] = '数据库服务器地址:端口';
$_config['db']['1']['dbuser'] = '数据库用户名';
$_config['db']['1']['dbpw'] = '数据库密码';
$_config['db']['1']['dbname'] = '库名';
// Redis 配置(本地)
$_config['memory']['redis']['server'] = '127.0.0.1';
$_config['memory']['redis']['port'] = 6379;
$_config['memory']['redis']['requirepass'] = '设置的密码';
config/config_ucenter.php
define('UC_DBHOST', '数据库服务器地址:端口');
define('UC_DBUSER', '数据库用户名');
define('UC_DBPW', '数据库密码');
define('UC_DBNAME', '库名');
define('UC_API', 'https://新域名/uc_server');
6. Redis 安全配置
测试环境 Redis 最初无密码,存在安全隐患。需要设置密码:
# 修改 Redis 配置文件
vim /etc/redis.conf
requirepass 你的密码
# 重启 Redis
systemctl restart redis
同时更新 config_global.php 中的 Redis 密码配置。
7. Nginx 站点配置
创建新的站点配置文件,关键配置:
server {
listen 80;
listen 自定义SSL端口 ssl http2;
server_name 新域名;
root %WEB_ROOT%/;
# SSL 配置
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# PHP 解析
include enable-php-fpm.conf;
# 伪静态规则
include /path/to/rewrite.conf;
}
如果需要保留后台访问的 Basic Auth 认证:
location ~* ^/admin* {
auth_basic "Authorization";
auth_basic_user_file /path/to/pass/file;
include enable-php-fpm.conf;
}
8. DNS 切换
将域名 DNS 解析指向新服务器,等待 DNS 生效。
9. 停用旧环境
# 停止旧 Web 服务
ssh 旧Web服务器 "service web-server stop"
# 停止旧 Nginx
ssh 旧附件服务器 "service nginx stop"
10. 清除缓存
# 清除 Discuz 缓存
rm -rf %WEB_ROOT%/data/cache/*
rm -rf %WEB_ROOT%/data/sysdata/*
rm -rf %WEB_ROOT%/data/template/*
# 清除 Redis 缓存
redis-cli -a '密码' FLUSHDB
# 重启 PHP
service php-fpm reload
# 重载 Nginx
nginx -t && nginx -s reload
踩坑记录
坑 1:企业微信登录跳转问题
迁移后访问首页被 302 重定向到企业微信登录页,提示 redirect_uri 与配置的授权完成回调域名不一致。
原因:企业微信后台应用的授权回调域名需要与当前域名一致。
解决:在企业微信后台修改授权回调域名为新域名即可。
坑 2:用户头像不显示(最折腾的一个)
迁移后首页用户头像显示为破损图片,但其他页面(论坛、帖子详情)头像正常。
排查过程:
- ✅ 确认
UC_API配置已改为新域名 - ✅ 确认头像文件
avatar.php工作正常 - ✅ 确认默认头像图片文件存在
- ✅ 清除 Discuz 文件缓存(
data/cache/、data/template/、data/sysdata/) - ✅ 清除浏览器缓存
- ❌ 问题依然存在
根因:pre_common_block_item 表的 fields 字段中,有多行数据序列化存储了旧域名的完整头像 URL。这些数据是 Discuz 门户系统(Portal Block)在生成模块内容时自动写入的,包含了硬编码的绝对路径。
修复:
UPDATE pre_common_block_item
SET fields = REPLACE(fields, '旧域名/uc_server/', '新域名/uc_server/')
WHERE fields LIKE '%旧域名%';
坑 3:首页装饰图标 404
首页底部某个装饰性小图标返回 404,导致浏览器显示破损图片占位符。
原因:模板 CSS 中引用了 hl_icon_sq.png,但该文件在服务器的 index/ 目录下不存在,实际存在于其他目录。
解决:从旧服务器复制正确的图标文件到引用路径对应的目录。
经验总结
-
Discuz 的缓存体系复杂:文件缓存、模板缓存、Redis/Memcache 缓存、数据库序列化数据,每一层都可能残留旧配置。迁移后需要逐层清理。
-
Block 模块数据容易遗漏:
pre_common_block_item.fields字段以序列化形式存储了包含绝对路径的数据,这是最容易被忽略的地方。 -
先预览再执行 SQL:对数据库做批量替换前,先用 SELECT 预览受影响的数据,确认替换逻辑无误后再执行 UPDATE。
-
企业微信配置:涉及第三方平台的应用配置时,除了服务器端配置,还需要同步修改第三方平台后台的回调域名。
-
Redis 安全:默认安装的 Redis 无密码且监听本地(127.0.0.1),建议设置密码增加安全性。
验证清单
迁移完成后建议逐项验证: