Discuz! 论坛迁移实战:从多机架构到单机部署完整记录

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:用户头像不显示(最折腾的一个)

迁移后首页用户头像显示为破损图片,但其他页面(论坛、帖子详情)头像正常。

排查过程

  1. ✅ 确认 UC_API 配置已改为新域名
  2. ✅ 确认头像文件 avatar.php 工作正常
  3. ✅ 确认默认头像图片文件存在
  4. ✅ 清除 Discuz 文件缓存(data/cache/data/template/data/sysdata/
  5. ✅ 清除浏览器缓存
  6. ❌ 问题依然存在

根因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/ 目录下不存在,实际存在于其他目录。

解决:从旧服务器复制正确的图标文件到引用路径对应的目录。

经验总结

  1. Discuz 的缓存体系复杂:文件缓存、模板缓存、Redis/Memcache 缓存、数据库序列化数据,每一层都可能残留旧配置。迁移后需要逐层清理。

  2. Block 模块数据容易遗漏pre_common_block_item.fields 字段以序列化形式存储了包含绝对路径的数据,这是最容易被忽略的地方。

  3. 先预览再执行 SQL:对数据库做批量替换前,先用 SELECT 预览受影响的数据,确认替换逻辑无误后再执行 UPDATE。

  4. 企业微信配置:涉及第三方平台的应用配置时,除了服务器端配置,还需要同步修改第三方平台后台的回调域名。

  5. Redis 安全:默认安装的 Redis 无密码且监听本地(127.0.0.1),建议设置密码增加安全性。

验证清单

迁移完成后建议逐项验证:

首页正常访问,布局完整
各板块列表正常
帖子详情页正常
用户头像显示正常(特别注意首页 Block 区域)
搜索功能正常
用户登录/登出正常
企业微信扫码登录正常
后台管理页面可访问
附件下载/查看正常
所有静态资源(CSS、JS、图片)返回 200
AI工具与实战

DeepSeek Harness 是什么?普通人能拿它干什么?

2026-8-22 22:44:49

流量卡必备知识

【全网评测】联通“海燕卡”深度拆解:29元200G+4年视频会员,长期捆绑套餐的得与失

2025-12-1 13:22:53

搜索