简单总结: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. 故障现象与初步排查
- 现象:
-
- 服务器本地
curl ``http://127.0.0.1:8090正常返回Halo页面,netstat -tlpn显示:
- 服务器本地
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 总结
- OpenResty 升级功能 Bug:内置升级多次失败,无明确报错指引,未适配第三方镜像兼容性;
- 异常清理激进 Bug:未校验应用实际服务状态(Halo 本身正常),仅因配置关联不一致就删除容器,无二次确认;
- 备份恢复逻辑缺失 Bug:恢复流程仅处理数据与数据库,未包含 “重建容器” 步骤,导致恢复后服务无法启动;
- 配置关联同步 Bug:手动修改容器后,1Panel 无法同步配置信息,需手动对齐参数。
四、预防措施与改进建议
- OpenResty 升级规范:
- 避免直接使用
latest标签,固定版本号(如 1.21.4.1),降低兼容性风险; - 升级前备份容器配置(
docker inspect 1Panel-openresty-xxx > openresty_config.json),便于快速回滚。
- 1Panel 操作前置检查:
- 执行 “重建 / 删除” 操作前,手动备份容器数据(
tar -zcvf halo_backup.tar.gz /opt/1panel/apps/halo/[应用目录]/data); - 恢复备份前,确认容器名、网络、挂载目录与备份一致,避免 “容器不存在” 报错。
- 配置固化与文档记录:
- 将 Halo 容器创建命令、核心参数(MySQL IP、数据库信息)写入
/opt/1panel/scripts/``halo_start.sh,添加执行权限,便于快速重建; - 记录应用版本、容器名、端口映射等关键信息到
README.md,避免参数混淆。
- 1Panel Bug 规避:
- 暂不依赖 1Panel 的 OpenResty 升级功能,手动升级时严格复用原容器参数;
- 备份恢复后,若容器未自动创建,直接执行手动重建命令,跳过 1Panel 的 “恢复” 流程。
五、总结
本次事故的核心是“OpenResty 新版本兼容性问题”,叠加“1Panel 多个功能 Bug” 导致故障扩大。
关键解决思路为:降级 OpenResty 恢复基础转发服务→提取备份参数→手动重建 Halo 容器补全 1Panel 缺失步骤”。
通过规范操作流程、规避 1Panel 已知 Bug、固化核心配置,可有效降低同类故障的发生概率与处理成本。
本次恢复后数据完整,未造成永久性损失。