侧边栏壁纸
博主头像
未完待续

记录电影、影像、生活,以及偶尔的折腾。

  • 累计撰写 6 篇文章
  • 累计创建 11 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

宝塔面板+Halo博客网站整机迁移记录

有心人无名氏
2026-08-27 / 0 评论 / 1 点赞 / 9 阅读 / 0 字

Halo 博客跨服务器迁移与恢复操作文档

1. 文档用途

本文记录一次实际完成的 Halo 博客服务器迁移过程。

适用于类似架构:

Ubuntu
├── 宝塔面板
│   ├── Nginx
│   ├── MySQL
│   └── 网站/SSL/反向代理配置
│
└── Docker
    └── Halo 2.26

网站访问链路:

用户
 ↓
域名
 ↓
Nginx 80/443
 ↓
反向代理
 ↓
127.0.0.1:8090
 ↓
Halo 2.26
 ↓
MySQL
 ↓
halo 数据库

本次迁移的核心思路是:

使用宝塔整机迁移恢复网站、Nginx 和 MySQL 数据库,然后在新服务器重新安装 Docker 和 Halo,让新的 Halo 直接连接迁移过来的原 halo 数据库。


2. 迁移前准备

迁移之前,建议至少准备两份备份。

2.1 宝塔备份

需要备份:

  • 网站

  • MySQL 数据库

  • Nginx 网站配置

  • SSL 相关配置

  • 宝塔管理的数据

如果新旧服务器都使用宝塔,可以优先使用:

宝塔 → 整机迁移

进行迁移。


2.2 Halo 后台备份

进入:

Halo Console
→ 备份
→ 创建备份

下载并妥善保存 Halo 备份文件。

这份备份主要作为第二道保险。

如果宝塔迁移过来的数据库能够直接恢复原站,就不需要使用 Halo 备份覆盖现有数据。

Halo 官方支持通过 Console 对站点进行完整备份和恢复。


3. 新服务器准备

建议新服务器安装与旧服务器相同或接近版本的 Ubuntu。

首先安装:

宝塔面板

然后通过宝塔整机迁移,将原服务器的数据迁移到新服务器。


4. 宝塔整机迁移

通过宝塔完成整机迁移后,检查:

网站
数据库
Nginx
SSL

是否已经恢复。

特别检查:

宝塔 → 数据库

本次迁移后发现原来的 Halo 数据库已经存在:

数据库名:halo
用户名:halo

这说明宝塔已经把 Halo 使用的 MySQL 数据库迁移到了新服务器。


5. 检查 Halo 数据库

进入 phpMyAdmin。

打开:

halo

本次数据库中存在:

extensions
migrations

不要因为只有两张表就认为数据库没有恢复。

Halo 2.x 的大量资源数据存储在 extensions 中。

可以通过 SSH 检查数据库。

/www/server/mysql/bin/mysql -h 127.0.0.1 -u halo -p halo

输入宝塔中显示的 halo 数据库密码。

进入 MySQL 后:

SHOW TABLES;

本次显示:

extensions
migrations

继续检查当前数据库用户:

SELECT CURRENT_USER();

本次结果:

halo@localhost

检查权限:

SHOW GRANTS;

确认 halo 用户拥有:

halo.*

数据库权限。

退出:

exit;

6. 检查 MySQL 监听状态

执行:

ss -lntp | grep 3306

本次服务器显示:

*:3306

说明 MySQL 正在监听 3306。

注意:

不要因为 Halo 需要访问 MySQL,就在腾讯云/其他云厂商安全组中向公网开放 3306。

Halo 和 MySQL 都运行在同一台服务器时,没有必要将数据库暴露到 Internet。


7. 检查 Docker

宝塔整机迁移并不会保证 Docker 环境和 Docker 容器一起迁移。

执行:

docker ps -a

如果出现:

Command 'docker' not found

说明新服务器还没有 Docker。


8. 安装 Docker

安装 Docker:

curl -fsSL https://get.docker.com | sh

安装完成后检查:

docker --version

以及:

docker compose version

本次环境为:

Docker 29.7.2
Docker Compose v5.5.0

版本号未来可能不同,只要 Docker 和 Compose 正常工作即可。


9. 创建 Halo 工作目录

本次将 Halo 放在:

/opt/halo2

创建:

sudo mkdir -p /opt/halo2
sudo chown -R $USER:$USER /opt/halo2
cd /opt/halo2

这里使用 /opt 只是为了把 Docker 应用与宝塔 /www 目录分开管理。

Halo 并不强制要求安装在 /opt

最终目录:

/opt/halo2/
├── docker-compose.yaml
└── data/

其中:

data/

映射到 Halo 容器中的:

/root/.halo2

这里以后会保存 Halo 的主题、插件、附件、日志、备份等工作目录数据,因此需要纳入服务器备份。


10. 创建 Halo Docker Compose

进入:

cd /opt/halo2

创建:

nano docker-compose.yaml

配置:

services:
  halo:
    image: registry.fit2cloud.com/halo/halo:2.26
    container_name: halo
    restart: unless-stopped

    network_mode: host

    volumes:
      - ./data:/root/.halo2

    command:
      - --server.port=8090
      - --spring.r2dbc.url=r2dbc:pool:mysql://127.0.0.1:3306/halo
      - --spring.r2dbc.username=halo
      - --spring.r2dbc.password=你的Halo数据库密码
      - --spring.sql.init.platform=mysql
      - --halo.external-url=https://你的域名

注意:

你的Halo数据库密码

必须填写宝塔数据库中 halo 用户的实际密码。

域名也必须替换为自己的实际域名。


11. 为什么使用 host 网络

本次数据库用户是:

halo@localhost

而 MySQL 运行在宿主机。

如果使用普通 Docker bridge 网络:

Halo Container
 ↓
Docker Network
 ↓
Host MySQL

MySQL 看到的连接来源不一定是 localhost。

因此本次使用:

network_mode: host

这样 Halo 可以直接连接:

127.0.0.1:3306

也不需要为了 Docker 将 MySQL 3306 暴露给公网。

Halo 官方 Docker Compose 文档同样提供了使用 network_mode: host 连接已有外部数据库的部署示例。


12. 检查 Compose 配置

保存文件后:

docker compose config

如果没有报错,说明 YAML 和 Compose 配置基本正确。

注意:

docker compose config

可能会直接显示数据库密码。

因此不要把输出截图公开到互联网。


13. 启动 Halo 前再次备份数据库

第一次启动新的 Halo 之前:

宝塔
→ 数据库
→ halo
→ 备份

创建一次数据库备份。

原因是 Halo 启动时可能进行数据库 migration。

如果发生版本或数据库异常,可以恢复到启动之前的状态。


14. 启动 Halo

执行:

cd /opt/halo2
sudo docker compose up -d

如果当前 Linux 用户已经加入 docker 用户组,可以省略 sudo


15. Docker permission denied 的处理

如果出现:

permission denied while trying to connect to the docker API

说明当前用户没有访问:

/var/run/docker.sock

的权限。

临时直接使用:

sudo docker compose up -d

即可。

如果希望以后不用 sudo

sudo usermod -aG docker $USER

然后:

退出 SSH
→ 重新登录

测试:

docker ps

16. 检查 Halo 容器

执行:

sudo docker ps

正常情况下应该看到:

halo
STATUS: Up ...

然后查看日志:

sudo docker logs halo --tail 100

正常日志中会出现类似:

Started Application
CategoryReconciler
UserReconciler
TagReconciler
ConfigMap
PolicyReconciler

如果旧数据库中已经存在用户、分类、标签等资源,Halo 会开始读取和同步这些数据。


17. 测试 8090

测试:

curl -I http://127.0.0.1:8090

本次根路径返回:

404 Not Found

这并不代表 Halo 没有启动。

继续测试后台:

curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8090/console

本次返回:

302

说明 Halo Console 路由已经正常工作。

因此判断 Halo 是否正常不能只看:

/

一个路径。

还需要结合:

docker ps
docker logs
/console

综合判断。


18. Nginx 反向代理

Halo 运行:

127.0.0.1:8090

宝塔中的网站通过 Nginx 反向代理到 Halo。

基本逻辑:

https://域名
       ↓
Nginx
       ↓
127.0.0.1:8090
       ↓
Halo

典型 Nginx 反向代理核心配置类似:

location / {
    proxy_pass http://127.0.0.1:8090;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

如果宝塔整机迁移已经恢复原网站配置,一般不需要重新创建。


19. 域名解析

确认域名:

A记录 → 新服务器公网IP

并确认服务器和云厂商安全组允许:

80/TCP
443/TCP

正常访问。

MySQL:

3306

不需要对公网开放。

Halo:

8090

如果只通过 Nginx 反向代理访问,同样没有必要向公网开放。


20. 测试 Halo 后台

浏览器访问:

https://你的域名/console

本次成功进入原来的 Halo 登录页面。

原来的管理员账号也已经从旧数据库恢复。

登录成功后,可以看到原来的:

  • 文章

  • 用户

  • 浏览量

  • 网站设置

  • 其他数据库内容

这说明:

宝塔整机迁移
       ↓
MySQL halo 数据库
       ↓
Halo 2.26

恢复成功。


21. 检查完整性

迁移完成后逐项检查:

  • 首页能够打开

  • Halo Console 可以登录

  • 原管理员账号存在

  • 文章数量正确

  • 文章内容正常

  • 分类正常

  • 标签正常

  • 页面正常

  • 附件和图片正常

  • 主题正常

  • 插件正常

  • 网站设置正常

  • Logo / Banner 正常

  • HTTPS 正常

  • 手机端正常

  • Nginx 反向代理正常

  • Halo 容器能够自动启动

  • MySQL 数据正常

全部确认后,才算迁移完成。


22. Halo 后台备份什么时候使用

如果:

宝塔整机迁移
→ halo 数据库完整
→ 新 Halo 可以读取旧数据

不要再使用 Halo 后台备份覆盖当前数据

Halo 后台备份作为灾难恢复手段保留即可。

只有在:

数据库没有迁移
数据库损坏
数据严重缺失
需要建立一个全新的 Halo

等情况下,再考虑:

Halo Console
→ 备份
→ 恢复

Halo 官方说明,备份恢复不限制部署方式和数据库类型,因此它非常适合作为跨服务器恢复的第二道保险。


23. 本次迁移过程中遇到的问题

问题一:宝塔整机迁移后没有 Docker

表现:

docker: command not found

原因:

宝塔整机迁移不等于操作系统磁盘克隆。

解决:

重新安装 Docker。


问题二:原 Halo 数据库其实已经迁移

最开始计划:

重新创建 MySQL
→ 安装 Halo
→ 上传 Halo 备份

后来发现:

宝塔数据库
→ halo

已经存在,而且包含:

extensions
migrations

因此改变方案:

新 Halo
 ↓
直接连接迁移过来的原 halo 数据库

最终成功恢复。


问题三:数据库用户只有 localhost 权限

检查:

SELECT CURRENT_USER();

得到:

halo@localhost

因此没有额外创建:

halo@%

而是让 Halo Docker 使用:

network_mode: host

直接连接:

127.0.0.1:3306

既简单,也避免为了 Docker 放宽数据库访问范围。


问题四:Docker permission denied

表现:

permission denied while trying to connect to the docker API

解决:

sudo docker compose up -d

长期解决:

sudo usermod -aG docker $USER

然后重新登录 SSH。


问题五:访问 8090 根目录返回 404

测试:

curl http://127.0.0.1:8090/

返回:

404

但:

curl http://127.0.0.1:8090/console

返回:

302

同时:

docker ps

显示容器:

Up

日志显示:

Started Application

最终通过域名:

https://域名/console

成功进入 Halo 后台。

所以:

单独看到 / 返回 404 时,不要立即判断 Halo 启动失败。


24. 最终服务器结构

迁移完成后的结构:

Ubuntu
│
├── 宝塔
│   │
│   ├── Nginx
│   │      ↓
│   │   HTTPS / 域名
│   │      ↓
│   │   127.0.0.1:8090
│   │
│   └── MySQL
│          ↓
│        halo
│
└── Docker
     │
     └── Halo 2.26
          │
          ├── /opt/halo2/data
          │
          └── 127.0.0.1:3306
                    ↓
                宝塔 MySQL

25. 日常备份建议

以后不要只依赖一种备份。

建议采用三层备份。

第一层:Halo 自带备份

定期:

Halo Console
→ 备份

至少保留最近几份。

第二层:MySQL 数据库备份

宝塔:

数据库
→ halo
→ 备份

建议开启定时数据库备份。

第三层:Halo 工作目录

重点备份:

/opt/halo2/

尤其:

/opt/halo2/docker-compose.yaml
/opt/halo2/data/

Halo 官方说明,工作目录中可能包含:

themes
plugins
attachments
logs
backups
application.yaml

所以数据库备份不能完全替代 Halo 工作目录备份。


26. 下次迁移的最简流程

以后再次迁移服务器,可以直接按照下面执行:

① Halo 后台创建完整备份

        ↓

② 宝塔备份网站和 halo 数据库

        ↓

③ 新服务器安装 Ubuntu + 宝塔

        ↓

④ 宝塔整机迁移

        ↓

⑤ 确认 halo 数据库存在

        ↓

⑥ 安装 Docker

        ↓

⑦ 创建 /opt/halo2

        ↓

⑧ 创建 docker-compose.yaml

        ↓

⑨ Halo 连接宝塔原 halo 数据库

        ↓

⑩ docker compose up -d

        ↓

⑪ 检查 docker ps / docker logs

        ↓

⑫ 检查 /console

        ↓

⑬ 检查 Nginx 反向代理

        ↓

⑭ 域名解析到新服务器

        ↓

⑮ 登录 Halo 后台

        ↓

⑯ 检查文章、附件、主题、插件

        ↓

⑰ 确认网站完整恢复

27. 重要安全注意事项

  1. 不要在公开截图中暴露数据库密码。

  2. 不要向公网开放 MySQL 3306,除非确实有远程数据库需求并配置严格的访问控制。

  3. docker-compose.yaml 包含数据库密码,应限制服务器文件访问权限。

  4. Halo、MySQL、宝塔和 Ubuntu 都应定期更新安全补丁。

  5. 修改服务器之前先备份数据库。

  6. Halo 升级之前先备份。

  7. 不要把唯一备份保存在网站所在的同一台服务器。

  8. 建议至少有一份备份保存在本地电脑或其他云存储中。

  9. 旧服务器不要在新服务器验证完成前立即销毁。

  10. SSL、DNS、安全组属于迁移验收的一部分,不要只检查 Halo 后台。


28. 常用维护命令

查看 Halo:

sudo docker ps

查看日志:

sudo docker logs halo --tail 100

实时查看日志:

sudo docker logs -f halo

重启 Halo:

sudo docker restart halo

进入 Halo Compose 目录:

cd /opt/halo2

停止:

sudo docker compose down

启动:

sudo docker compose up -d

检查 Compose:

sudo docker compose config

查看 8090:

ss -lntp | grep 8090

查看 MySQL:

ss -lntp | grep 3306

测试 Halo Console:

curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8090/console

查看磁盘:

df -h

查看 Docker 磁盘占用:

sudo docker system df

29. 核心恢复原则

这次迁移最值得保留的经验是:

宝塔负责迁移宝塔能够管理的数据,Docker 应用则需要单独确认。

对于 Halo 网站,真正需要关注的是:

数据库
+
Halo 工作目录
+
Docker Compose 配置
+
Nginx
+
SSL
+
DNS

只要这些核心数据都存在,即使原服务器完全不存在,也可以在一台新的 Ubuntu 服务器上重新搭建 Halo 并恢复网站。

因此以后不要把“服务器”本身当成唯一资产。

真正需要长期保存的是:

数据
配置
备份
恢复文档

有了这些,即使更换腾讯云、阿里云、AWS 或其他云服务器,也能重新恢复网站。

1
博主关闭了所有页面的评论