PbootCMS网站迁移服务器教程:程序、数据库与伪静态配置

公司官网用的是 PbootCMS,服务商到期要换云,或者要把测试站搬到正式服务器。看起来不过是“复制文件 + 导数据库”两件事,但每次迁移总会冒出各种毛病:首页能开、内页全 404;后台进得去、登录验证码出不来;栏目页面打开是 Nginx 404 而不是 CMS 的 404;图片全裂。这些问题九成不是 PbootCMS 本身的问题,而是伪静态规则没配、数据库配置没改、目录权限没给对。

本文按“准备 → 搬程序 → 搬数据 → 改配置 → 配伪静态 → 权限加固 → 验证”的顺序,给出一套可完整复用的 PbootCMS 迁移流程。命令以 CentOS 7/8、AlmaLinux、Ubuntu 20.04/22.04 通用为前提,PHP 版本以 7.4 / 8.1 为例,不同版本路径请按实际调整。

一、迁移前:先摸清现状并做好备份

很多人上来就打包文件,结果漏了数据库或漏了附件。第一步是把老环境的“资产清单”列清楚。

1.1 确认关键信息

# 1. PHP 版本与已装扩展(新环境必须一致或更高)
php -v
php -m | grep -E 'gd|curl|openssl|mbstring|mysqli|pdo_mysql|pdo_sqlite|fileinfo|sqlite3'

# 2. Web 服务器类型与版本
httpd -v 2>/dev/null || nginx -v

# 3. MySQL 版本(SQLite 站点跳过)
mysql -V

# 4. 站点根目录与容量
du -sh /data/www/pboot/*
du -sh /data/www/pboot

# 5. 确认 PbootCMS 用的数据库类型:看配置文件
cat /data/www/pboot/config/database.php

1.2 备份三件套

# 程序文件(保留权限、软链、时间戳)
cd /data/www && tar czf /backup/pboot_$(date +%F).tar.gz pboot

# 数据库(MySQL)
mysqldump -uroot -p --single-transaction --default-character-set=utf8mb4 \
  --routines --triggers pbootdb | gzip > /backup/pboot_db_$(date +%F).sql.gz

# SQLite 站点:数据库就是文件,必须和业务文件一起备份(通常在 data/ 目录)
ls -lh /data/www/pboot/data/*.db
cp -a /data/www/pboot/data /backup/pboot_data_$(date +%F)

# 别忘配置文件本身
cp -a /data/www/pboot/config /backup/pboot_config_$(date +%F)

提醒:备份完成后,务必用 tar tzf 备份包 | wc -l 抽查一遍能否正常解出,没验过完整性就不算备份。

二、新环境准备:PHP 扩展一个都不能少

PbootCMS 对 PHP 版本要求不高(5.4 以上即可运行),但缺扩展会直接白屏或功能异常。常见必备扩展:

扩展缺失时的症状安装示例(Ubuntu)
mysqli 或 pdo_mysql数据库连接失败、安装向导报错apt install php8.1-mysql
pdo_sqlite / sqlite3SQLite 版站点无法读写数据apt install php8.1-sqlite3
gd验证码图片无法显示、缩略图生成失败apt install php8.1-gd
curl在线更新、远程接口调用失败apt install php8.1-curl
mbstring中文截取乱码、后台部分功能异常apt install php8.1-mbstring
fileinfo上传附件校验失败apt install php8.1-fileinfo(通常内置)
opensslHTTPS 请求、邮件发送失败一般默认已安装
# CentOS / AlmaLinux 系列(含 Remi 源)
yum install -y nginx php php-fpm php-mysqlnd php-gd php-mbstring php-curl php-sqlite3
systemctl enable --now nginx php-fpm

# Ubuntu / Debian 系列
apt update && apt install -y nginx php8.1-fpm php8.1-mysql php8.1-gd \
  php8.1-mbstring php8.1-curl php8.1-sqlite3
systemctl enable --now nginx php8.1-fpm

# 核对 PHP-FPM 运行用户,后面配权限要用
grep -nE '^\s*(user|group)\s*=' /etc/php/8.1/fpm/pool.d/www.conf
ps aux | grep php-fpm | grep -v grep | awk '{print $1}' | sort -u

三、迁移程序文件

推荐 rsync,可断点续传、保留权限,大附件目录也不怕中断重来。

# 先 dry-run 预览,确认目标路径没写错
rsync -avzHP --dry-run -e 'ssh -p 22' root@老机IP:/data/www/pboot/ /data/www/pboot/

# 正式同步(-a 保留权限属主软链,-P 断点续传+进度)
rsync -avzHP -e 'ssh -p 22' root@老机IP:/data/www/pboot/ /data/www/pboot/

# 若老机无法直连:先在老机打包,再传包
# 老机:tar czf /tmp/pboot.tgz -C /data/www pboot
# 新机:scp root@老机IP:/tmp/pboot.tgz /tmp/ && tar xzf /tmp/pboot.tgz -C /data/www

同步后核对一致性——用文件总数和总体积对账,是发现“漏拷”最省事的办法:

# 两台机器上分别执行,数字应完全一致
find /data/www/pboot -type f | wc -l
du -sb /data/www/pboot

# 重点核对这几个目录是否齐全
ls /data/www/pboot
# 正常应看到:index.php admin.php config/ core/ apps/ template/ static/ data/ runtime/

四、迁移数据库

4.1 MySQL 版

# 老机导出(务必指定 utf8mb4,避免中文乱码/表情丢失)
mysqldump -uroot -p --single-transaction --default-character-set=utf8mb4 \
  --routines --triggers pbootdb | gzip > /tmp/pboot.sql.gz

# 新机建库(字符集必须一致)
mysql -uroot -p -e "CREATE DATABASE pbootdb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
mysql -uroot -p -e "CREATE USER 'pboot'@'localhost' IDENTIFIED BY '强密码'; GRANT ALL ON pbootdb.* TO 'pboot'@'localhost'; FLUSH PRIVILEGES;"

# 导入
zcat /tmp/pboot.sql.gz | mysql -uroot -p --default-character-set=utf8mb4 pbootdb

# 校验:表数量与本机的前缀是否一致(PbootCMS 常见前缀为 ay_)
mysql -uroot -p -e "USE pbootdb; SHOW TABLES;" | wc -l
mysql -uroot -p -e "USE pbootdb; SHOW TABLES LIKE 'ay_%';" | head -20

4.2 SQLite 版

# SQLite 没有导入导出,直接拷 .db 文件即可,但必须确认源文件没有处于写状态
ls -lh /data/www/pboot/data/
cp -a /data/www/pboot/data/*.db /backup/

# 完整性检查
php -r '$d=new PDO("sqlite:/data/www/pboot/data/pbootcms.db"); var_dump($d->query("select count(*) from ay_content")->fetchColumn());'

五、修改配置文件

PbootCMS 的数据库连接信息在 config/database.php,站点域名与路径相关配置在 config/config.php。凡是写死的域名、绝对路径都要在这里和数据库里改。

# 查看并修改数据库连接配置
cat /data/www/pboot/config/database.php

# 典型内容(按实际情况修改 host / user / passwd / dbname)
return array(
    'database' => array(
        'type'   => 'mysqli',      // mysqli / pdo / sqlite
        'host'   => 'localhost',   // 同机用 localhost 或 127.0.0.1
        'user'   => 'pboot',
        'passwd' => '强密码',
        'port'   => '3306',
        'dbname' => 'pbootdb',
        'dbprefix' => 'ay_',       // 表前缀,必须与老库一致
    )
);
# 查找所有写死的老域名 / 老 IP / 老绝对路径
grep -rnE 'old-domain\.com|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' \
  /data/www/pboot/config /data/www/pboot/template | head -30

# 数据库里也要查(站点配置常写在数据表中)
zcat /tmp/pboot.sql.gz | grep -oE 'https?://[a-zA-Z0-9./_-]*(old-domain|老域名)[a-zA-Z0-9./_-]*' | sort | uniq -c | head

优先用后台改:登录后台后,在“系统设置 → 参数配置 / 站点信息”里直接改域名,比改数据库安全。只有后台进不去时才考虑直接改库,且改前必须备份。

六、伪静态配置(PbootCMS 迁移的头号坑)

PbootCMS 的栏目页、内容页都是“友好 URL”(如 /about/、/news/12.html),这些地址在磁盘上并不真实存在,必须由 Web 服务器把请求转发给 index.php。转发规则没配,所有内页就是 404。

6.1 Nginx 规则

server {
    listen 80;
    server_name www.example.com;
    root /data/www/pboot;
    index index.php index.html index.htm;

    access_log /var/log/nginx/pboot.access.log;
    error_log  /var/log/nginx/pboot.error.log;

    # PbootCMS 伪静态核心规则:文件/目录不存在时,交给 index.php 处理
    location / {
        if (!-e $request_filename) {
            rewrite ^(.*)$ /index.php?p=$1 last;
        }
    }

    # 后台入口(若后台文件名保持 admin.php,此段可省略,但建议加上更稳妥)
    location /admin/ {
        if (!-e $request_filename) {
            rewrite ^/admin/(.*)$ /admin.php?p=$1 last;
        }
    }

    location ~ \.php$ {
        fastcgi_pass   unix:/run/php/php8.1-fpm.sock;
        fastcgi_index  index.php;
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_connect_timeout 5s;
        fastcgi_read_timeout    60s;
    }

    # 安全:禁止访问敏感目录
    location ~* ^/(config|core|data|runtime|apps)/.*\.(php|db|sql)$ {
        deny all;
    }

    # 静态资源加速
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
        expires 30d;
        access_log off;
    }
}

也可以使用更现代的 try_files 写法,效果等价且性能更好(少了 if 判断):

location / {
    try_files $uri $uri/ /index.php?p=$uri&$args;
}

注意:if 指令在 location 中配合 rewrite ... last 是 Nginx 官方认可的安全用法,不必过度担心;两种写法任选一种,不要同时写两套,否则会出现路由冲突。

6.2 Apache 规则对照

场景Apache(.htaccess)Nginx
前端路由转发RewriteRule ^(.*)$ index.php?p=$1 [QSA,PT,L]rewrite ^(.*)$ /index.php?p=$1 last;
前置条件RewriteCond %{REQUEST_FILENAME} !-f / !-dif (!-e $request_filename) 或 try_files
生效方式放在站点根目录 .htaccess,自动生效必须写进 server 块并 nginx -s reload
是否需模块需开启 mod_rewrite 且 AllowOverride All无需额外模块
常见失效原因AllowOverride None,.htaccess 被忽略规则写在错误的 server/location,或未 reload

从 Apache 迁到 Nginx 时,最容易忘的就是这一步:.htaccess 不会被 Nginx 读取,必须手工翻译成 Nginx 规则。

# 改完一定要校验语法并平滑加载
nginx -t
systemctl reload nginx

# 验证:内页应返回 200,而不是 Nginx 的 404
curl -s -o /dev/null -w "%{http_code}\n" http://www.example.com/about/
curl -s -o /dev/null -w "%{http_code}\n" http://www.example.com/news/12.html

七、权限、安全与验证清单

7.1 目录权限

# 假设 PHP-FPM 运行用户为 www-data(CentOS 常见为 nginx)
chown -R www-data:www-data /data/www/pboot
find /data/www/pboot -type d -exec chmod 755 {} \;
find /data/www/pboot -type f -exec chmod 644 {} \;

# 需要写入的目录(上传、缓存、SQLite 数据目录)
chmod -R 775 /data/www/pboot/data /data/www/pboot/runtime /data/www/pboot/static/upload

# 以 Web 用户身份验证写权限
sudo -u www-data touch /data/www/pboot/runtime/test.txt && echo "可写" || echo "不可写"
rm -f /data/www/pboot/runtime/test.txt

# CentOS 的 SELinux 别忘了
getenforce
semanage fcontext -a -t httpd_sys_rw_content_t '/data/www/pboot/(data|runtime)(/.*)?'
restorecon -Rv /data/www/pboot

7.2 安全加固建议

  1. 修改后台入口文件名:把 admin.php 改成不易猜的名字(如 manage_a7f3.php),并同步修改 Nginx 里的转发规则,能挡掉绝大多数扫描。
  2. 禁止外网访问 config/、core/、data/、runtime/ 下的脚本与 .db 文件。
  3. 后台加 IP 白名单(Nginx allow / deny)或 HTTP Basic 认证,做第二道防线。
  4. 删除根目录下的 install 相关安装入口(若存在),防止被二次安装。
  5. 站点上线前把 display_errors 设为 Off,错误写日志。
  6. 不要给任何目录开 777;775 已经足够。
location /admin/ {
    allow 203.0.113.0/24;   # 办公网出口
    deny  all;
    try_files $uri $uri/ /manage_a7f3.php?p=$uri&$args;
}

7.3 迁移后验证清单

  1. 首页、栏目页、内容页、标签页逐个 curl,状态码应为 200。
  2. 后台登录页可打开,验证码图片能正常显示(gd 扩展是否装好的试金石)。
  3. 登录后台,在“系统设置 → 站点信息”里确认域名已改为新域名。
  4. 上传一张测试图片,确认能上传且前台能显示。
  5. 发一篇测试文章,确认能保存并能在前台访问。
  6. 检查模板目录 template/ 是否完整,首页样式是否正常(CSS/JS 是否 404)。
  7. 对比新老首页 HTML 的 MD5,除统计代码外应基本一致。
  8. 检查附件目录文件数是否与老站一致。
  9. 看 tail -f /var/log/nginx/pboot.error.log 有无 Permission denied、No such file 等错误。
  10. 老域名做 301 跳转到新域名,并在站长平台提交改版。

八、常见问题速查

现象原因处理
首页正常,内页全部 Nginx 404伪静态规则未配置或未 reload加 rewrite 规则,nginx -t && systemctl reload nginx
后台验证码不显示gd 扩展缺失,或 session/runtime 目录不可写装 php-gd;给 runtime 目录写权限
登录后立刻跳回登录页session 目录权限、域名变化导致 cookie 失效清理浏览器 cookie;检查 /var/lib/php/sessions 权限
页面空白无任何输出PHP 报错被隐藏,或 opcache 缓存了旧路径查 php error_log;重载 php-fpm 清空 opcache
数据库连接失败config/database.php 账号密码/库名不对核对配置;确认 MySQL 用户权限
中文变问号或乱码导入时字符集不是 utf8mb4重新按 utf8mb4 导出导入;核对表字符集
图片裂图(404/403)附件未拷贝、权限不对、或页面仍指向老域名补同步 upload 目录;查权限;替换数据库中的老域名
样式丢失、页面裸奔static/ 或 template/ 未完整迁移比对文件数与体积,补 rsync

小结

PbootCMS 迁移的技术门槛不高,难点在于“不要漏项”。把流程固化成三句口诀会好记很多:文件用 rsync -a 拷、数据库用 utf8mb4 导、伪静态必须重写并 reload。剩下的权限、后台入口改名、IP 白名单属于安全加固,顺手一起做掉。

避坑清单:

  • 千万不要只拷程序不拷附件,用 find | wc -l 和 du -sb 对账,不信肉眼。
  • SQLite 站点没有“导数据库”这一步,直接拷 data/*.db 文件即可,很多人反而找不到。
  • 表前缀(常见 ay_)必须与老库保持一致,否则会提示表不存在。
  • Apache 的 .htaccess 在 Nginx 下完全无效,必须手工翻译。
  • 后台入口务必改名,不改名的 PbootCMS 站点几乎必然被扫描爆破。
  • 迁移完成后老域名要做 301,并把 robots.txt、sitemap 一并检查。
  • 整个迁移过程中始终保持老机运行,确认新站完全正常再切换 DNS。

关键词回顾:PbootCMS 迁移、服务器迁移教程、config/database.php、Nginx 伪静态 rewrite、index.php?p=、目录权限、SELinux。