个人博客服务异常恢复事故处理记录

96 阅读7分钟

简单总结:1Panel 的一个小 Bug 诱发了故障又导致排除过程中的种种新故障——若干 Bugs

一、事故概述

  • 时间:2025 年 11 月
  • 核心诱因:1Panel 内置 OpenResty(Docker 容器部署)升级功能多次失败,手动升级至第三方镜像最新版后触发连锁故障。

为解决升级问题花了一整晚,最后从腾讯云安装了不那么新的最新版 focal

  • 故障链:OpenResty 升级兼容性问题→80/443 端口外部访问被拒→1Panel Bug误删 Halo 容器→备份恢复遇 1Panel Bug→手动重建 Halo 容器解决
  • 环境:1Panel 面板 + Docker(Halo Pro 2.21.10 + OpenResty 1.25.x→降级回 1.21.x + MySQL 8.x)
  • 影响:目标域名(如xxx.cn)中断访问约 24 小时,Halo 容器被删,依赖备份恢复数据(恢复后数据完整)

二、事故关键阶段与细节(按时间线)

阶段 1:手动升级 OpenResty触发故障

1. 升级背景与操作

  • 前置问题:1Panel“应用→OpenResty→升级” 功能多次失败(提示 “镜像拉取超时”“配置冲突”),当前为 Docker 部署的 1.21.x 版本,需升级修复安全漏洞
  • 手动操作
# 停止原1Panel管理的OpenResty容器
docker stop 1Panel-openresty-xxx  # 容器名脱敏
# 拉取第三方镜像的OpenResty最新版(1.25.x)
docker pull [第三方镜像仓库]/openresty/openresty:latest
# 基于新镜像创建容器,复用原端口、网络与挂载目录
docker run -d \
 --name 1Panel-openresty-xxx \
 --network 1panel-network \
 -p 80:80 -p 443:443 \
 -v /www/server/openresty:/usr/local/openresty/nginx/conf \
 -v /www/sites:/www/sites \
 [第三方镜像仓库]/openresty/openresty:latest

2. 故障现象与初步排查

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      169289/nginx: maste
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      169289/nginx: maste

(端口由容器内nginx: master进程通过docker-proxy映射至宿主机);

  • 本地 curl ``http://127.0.0.1:8090正常返回 Halo 博客页面,说明 Halo 容器配置正确、数据完整、服务正常;
  • 外部通过公网 IP / 域名访问 80/443 端口,均返回“Connection refused”,排除云服务器安全组(已开放 80/443)与系统防火墙(ufw status为 inactive)问题。
  • 排查结论

新版本 OpenResty 容器存在网络转发 / 配置兼容性问题,导致外部流量无法正常转发至 Halo 容器,Halo 本身服务无异常。

阶段 2:降级OpenResty,1Panel 操作扩大故障(Halo 容器被删)

1. 尝试修复 OpenResty 无效

  • 通过 1Panel“应用→OpenResty→重建” 功能选择原 1.21.x 版本,提示 “配置文件目录关联失败”;
  • 手动校验配置文件无语法错误,但 1Panel 无法正常管理新版本容器,推测升级后配置关联关系断裂。

2. 重建网站导致容器被删

  • 因 OpenResty 无法恢复,尝试通过 1Panel“一键部署网站” 重建网站关联Halo文件和MySql数据。过程中 1Panel 检测到 “Halo 应用配置与面板数据库记录不一致”,触发 “异常清理” 机制,未提示二次确认即删除原 Halo 容器(1Panel-halo-xxx);
  • 验证:docker ps -a | grep halo无结果,运行Halo的容器1Panel-halo-xxx被 1Panel自动删除,对应Halo目录被删除(附件文件等均被删除)。
  • 数据:还好MySql数据库仍在正常运行(而且已备份)、Halo已完整备份。

阶段 3:降级 OpenResty 与 Halo 备份恢复(遇 1Panel Bug)

1. 删除、重装低版本OpenResty恢复基础服务

  • 手动删除新版本OpenResty容器,指定低版本 1.21.x 镜像重建网站并一键部署Halo,一次性通过,非常顺利;
  • 验证:外部访问http://服务器公网IP正常返回 Halo 页面,基础反向代理功能恢复。

接下来只需要恢复Halo与数据库的连接,并恢复主题、附件等数据。

2. 1Panel 备份恢复Halo遇 Bug

  • 首次恢复失败:通过 1Panel“应用→Halo→恢复备份” 选择最新备份,提示 “容器 1Panel-halo-xxx 不存在,无法执行恢复”——推测因为备份时容器名称不一致;
  • 临时解决容器名问题:在主机用命令手动重命名容器:
docker stop 1Panel-halo-yyy

docker rename 1Panel-halo-yyy 1Panel-halo-xxx

docker start 1Panel-halo-xxx
  • 二次恢复 “假成功” :再次执行恢复,1Panel 日志显示 “删除旧数据库→创建新数据库→覆盖 /data 目录→恢复成功”,但恢复后无法访问网站,查看发现Halo容器消失:docker ps | grep halo无结果。
  • 定位 Bug:反复“多次删除、一键部署网站”进行测试,确认恢复过程中容器被删除且未自动重建。得出结论:1Panel 备份恢复功能仅包含 “数据覆盖 + 数据库操作”,缺失 “根据备份配置重建Halo容器” 步骤,属于设计缺陷。

接下来需要手工恢复Halo容器、必要时手工解压缩导入文件数据。

阶段 4:手动重建 Halo 容器(数据恢复与服务修复)

1. 准备好关键数据

  • MySQL 容器 IP:172.18.0.2
  • 库名halo_[数据库标识]、用户名halo_[用户标识]、密码[数据库密码脱敏]

2. 手动创建 Halo 容器(解决参数匹配问题)

  • 首次失败:误用 Halo 免费版镜像,无法启动容器;
  • 第二次失败:Halo版本不正确,数据库连接串不正确,无法启动容器;
  • 第三次失败:数据库连接串中的MySql容器地址不对(AI建议用容器名),容器不断重启;
  • 逐步修正各种问题后,将连接串改为用MySql容器的内网IP最终成功

3. 验证与收尾

三、1Panel 核心 Bug 总结

  1. OpenResty 升级功能 Bug:内置升级多次失败,无明确报错指引,未适配第三方镜像兼容性;
  2. 异常清理激进 Bug:未校验应用实际服务状态(Halo 本身正常),仅因配置关联不一致就删除容器,无二次确认;
  3. 备份恢复逻辑缺失 Bug:恢复流程仅处理数据与数据库,未包含 “重建容器” 步骤,导致恢复后服务无法启动;
  4. 配置关联同步 Bug:手动修改容器后,1Panel 无法同步配置信息,需手动对齐参数。

四、预防措施与改进建议

  1. OpenResty 升级规范
  • 避免直接使用latest标签,固定版本号(如 1.21.4.1),降低兼容性风险;
  • 升级前备份容器配置(docker inspect 1Panel-openresty-xxx > openresty_config.json),便于快速回滚。
  1. 1Panel 操作前置检查
  • 执行 “重建 / 删除” 操作前,手动备份容器数据(tar -zcvf halo_backup.tar.gz /opt/1panel/apps/halo/[应用目录]/data);
  • 恢复备份前,确认容器名、网络、挂载目录与备份一致,避免 “容器不存在” 报错。
  1. 配置固化与文档记录
  • 将 Halo 容器创建命令、核心参数(MySQL IP、数据库信息)写入/opt/1panel/scripts/``halo_start.sh,添加执行权限,便于快速重建;
  • 记录应用版本、容器名、端口映射等关键信息到README.md,避免参数混淆。
  1. 1Panel Bug 规避
  • 暂不依赖 1Panel 的 OpenResty 升级功能,手动升级时严格复用原容器参数;
  • 备份恢复后,若容器未自动创建,直接执行手动重建命令,跳过 1Panel 的 “恢复” 流程。

五、总结

本次事故的核心是“OpenResty 新版本兼容性问题”,叠加“1Panel 多个功能 Bug” 导致故障扩大。

关键解决思路为:降级 OpenResty 恢复基础转发服务→提取备份参数→手动重建 Halo 容器补全 1Panel 缺失步骤”。

通过规范操作流程、规避 1Panel 已知 Bug、固化核心配置,可有效降低同类故障的发生概率与处理成本。

本次恢复后数据完整,未造成永久性损失。