8840c4398a
- Downgrade Next.js 16→14.2, React 19→18.3, Tailwind 4→3.4 - Add comprehensive GA4 error monitoring system - Create Jenkins CI/CD pipeline with quality gates - Fix build issues: ESLint, SWC conflict, config format - Add documentation for deployment and error tracking
20 KiB
20 KiB
Novalon Website 回滚流程指南(生产环境专用)
最后更新: 2026-05-12 适用项目: novalon-website (四川睿新致远科技有限公司官网) 部署架构: 静态导出 + Docker + Nginx + CDN 目标恢复时间: < 10 分钟(P0 级别故障)
⚠️ 重要提示:本文档已针对你的实际部署环境定制,请勿使用通用模板!
📋 你的实际部署架构
┌─────────────────────────────────────────────────────┐
│ 开发机 (Local) │
│ - 项目路径: /Users/zhangxiang/Codes/Novalon/ │
│ novalon-website │
│ - 构建命令: npm run build:clean │
│ - 输出目录: dist/ │
│ - 部署命令: ./deploy-dist.sh │
└──────────────────────┬──────────────────────────────┘
│ rsync + SSH (root@139.155.109.62)
▼
┌─────────────────────────────────────────────────────┐
│ 生产服务器 (139.155.109.62) │
│ └── /home/novalon/docker-app/ │
│ ├── novalon-static/ ← 当前版本 │
│ ├── novalon-static_backup_* ← 自动备份 │
│ └── docker-compose.yml │
│ └── novalon-nginx-secure ← Nginx 容器 │
└──────────────────────┬──────────────────────────────┘
│ 反向代理
▼
┌─────────────────────────────────────────────────────┐
│ 用户访问 │
│ - 主域名: https://novalon.cn │
│ - 备用 IP: https://139.155.109.62 │
│ - HTTP → HTTPS 自动跳转 │
└─────────────────────────────────────────────────────┘
🚨 触发条件(满足任一即启动回滚)
P0 - 紧急故障(立即回滚,无需审批)
- 首页完全白屏或返回 500/502/503/504
- 所有页面无法访问(HTTP 状态码非 200)
- 安全漏洞报告(XSS、数据泄露、恶意重定向)
- 域名解析失败或 SSL 证书过期
P1 - 严重问题(30 分钟内回滚)
- 核心功能不可用:
- 导航栏无法点击
- 表单提交失败(联系表单、订阅等)
- 主题切换失效
- 移动端布局错乱
- 关键 SEO 元数据丢失:
<title>为空或显示 "Untitled"<meta name="description">缺失- Open Graph / Twitter Card 标签缺失
- 性能严重退化:
- Lighthouse Performance < 50(之前 > 90)
- LCP (Largest Contentful Paint) > 5 秒
- FID (First Input Delay) > 300ms
P2 - 一般问题(24 小时内修复)
- 次要页面样式异常(不影响核心功能)
- 图片资源加载失败(非首屏图片)
- 控制台有警告但无错误
🔄 Type 1:代码回滚(最常用,推荐首选)
适用场景
- 最近一次部署引入了 bug
- 需要快速恢复到上一个稳定版本
- Git 历史清晰,可以定位到稳定的 commit
Step 0:准备阶段(2 分钟)
# 0.1 确认当前状态
echo "=== 当前时间 ==="
date '+%Y-%m-%d %H:%M:%S'
echo ""
echo "=== 当前 Git 分支和 Commit ==="
git branch --show-current
git log --oneline -3
echo ""
echo "=== 检查是否有未提交的更改 ==="
git status --short
预期输出示例:
=== 当前时间 ===
2026-05-12 15:30:00
=== 当前 Git 分支和 Commit ===
main
abc1234 (HEAD -> main) feat: update hero animation
def5678 fix: improve mobile layout
ghi9012 chore: upgrade dependencies
=== 检查是否有未提交的更改 ===
M src/components/Hero.tsx
Step 1:确认问题现象(2 分钟)
# 1.1 检查网站是否可访问
curl -I https://novalon.cn/ | head -10
# 预期输出: HTTP/2 200
# 如果看到 500/502/503/504,说明需要紧急回滚
# 1.2 检查关键页面的 HTTP 状态码
for page in "/" "/about" "/contact" "/products" "/solutions"; do
status=$(curl -s -o /dev/null -w "%{http_code}" "https://novalon.cn${page}")
echo "$page -> $status"
done
# 预期输出: 所有页面都返回 200
# 1.3 检查关键 HTML 元素是否存在
curl -s https://novalon.cn/ | grep -E '<title>|<meta name="description">|<h1'
预期输出示例:
/ -> 200
/about -> 200
/contact -> 200
/products -> 200
/solutions -> 200
<title>四川睿新致远科技有限公司</title>
<meta name="description" content="..." />
<h1 class="...">...</h1>
如果上述检查有任何一项不通过,立即进入 Step 2。
Step 2:定位稳定版本(3 分钟)
# 2.1 查看 Git 历史,找到最近的稳定版本
git log --oneline --graph -20
# 寻找标记为 "stable"、"fix:"、"chore:" 的 commit
# 或者查看 Git Tags
git tag -l 'v*' --sort=-v:refname | head -5
# 如果没有 Tag,根据 commit message 判断
# 推荐选择最近一次包含以下关键词的 commit:
# - "fix:" (bug 修复)
# - "release:" 或 "v*.*.*" (正式发布)
# - "chore: bump version" (版本号更新)
示例输出:
* abc1234 (HEAD -> main) feat: update hero animation ← 当前版本(有问题)
* def5678 fix: improve mobile layout ← 可能是稳定版本
* ghi9012 chore: upgrade dependencies ← 上一个版本
* jkl3456 release: v1.0.0-stable ← 正式发布版(最安全)
决策建议:
- 如果
def5678是你上次验证过的版本,回滚到它 - 如果不确定,选择
jkl3456(Tagged release)
Step 3:执行本地代码回滚(3 分钟)
# 3.1 备份当前版本(以防万一)
git stash push -m "backup-before-rollback-$(date +%Y%m%d_%H%M%S)"
# 或者创建一个新的分支保存当前代码
git branch backup/broken-version-$(date +%Y%m%d)
# 3.2 切换到稳定版本
# 方法 A:使用 Git Tag(推荐)
git checkout v1.0.0-stable
# 方法 B:使用 Commit Hash
git checkout def5678
# 3.3 确认已切换成功
git log --oneline -1
# 应该显示: def5678 fix: improve mobile layout
echo "✅ 已切换到稳定版本"
Step 4:重新构建并部署(5 分钟)
# 4.1 清理并构建
npm run build:clean
# 如果构建成功,会看到类似输出:
# ✅ Built in Xs
# 📁 生成了 XXX 个文件,总大小: XX MB
# 4.2 快速验证构建产物
if [ -d "dist" ]; then
echo "✅ dist 目录存在"
# 检查关键文件是否存在
ls -lh dist/index.html
ls -lh dist/about/index.html
ls -lh dist/contact/index.html
# 检查 HTML 内容
head -20 dist/index.html | grep '<title>'
else
echo "❌ 构建失败!dist 目录不存在"
exit 1
fi
# 4.3 部署到生产环境
./deploy-dist.sh
# 脚本会自动执行:
# 1. 检查 dist 目录
# 2. 验证 SSH 连接
# 3. 备份旧版本(在服务器上)
# 4. 上传新的 dist
# 5. 设置权限
# 6. 重载 Nginx
# 7. 验证部署结果
Step 5:验证回滚成功(2 分钟)
# 5.1 等待 3-5 秒让 CDN 缓存刷新
sleep 5
# 5.2 再次执行 Step 1.2 和 1.3 的检查
for page in "/" "/about" "/contact" "/products"; do
status=$(curl -s -o /dev/null -w "%{http_code}" "https://novalon.cn${page}")
if [ "$status" = "200" ]; then
echo "✅ $page -> $status"
else
echo "❌ $page -> $status (需要进一步排查)"
fi
done
# 5.3 浏览器手动验证(重要!)
open https://novalon.cn/
# 手动检查清单:
# □ 首页正常加载,无白屏
# □ 导航栏可点击,所有链接正常工作
# □ Logo 显示正确(应该是书法字体)
# □ 主题切换按钮可用(如果有暗色模式)
# □ 移动端布局正常(可以用 Chrome DevTools 模拟)
# □ 表单可以打开(即使不提交)
Step 6:通知相关人员(2 分钟)
# 6.1 记录回滚操作日志
cat << EOF >> /tmp/rollback-log.txt
==========================================
回滚记录
==========================================
时间: $(date '+%Y-%m-%d %H:%M:%S')
操作人: $(whoami)
原因: [填写具体原因]
回滚前版本: abc1234 (feat: update hero animation)
回滚后版本: $(git log --oneline -1)
验证结果: ✅ 所有关键页面正常
耗时: 约 15 分钟
==========================================
EOF
# 6.2 发送通知(钉钉/企业微信/邮件)
# 示例:发送邮件给 dev-team@novalon.cn
cat << EOF | mail -s "⚠️ 已回滚 Novalon Website" dev-team@novalon.cn
Novalon Website 已完成紧急回滚
回滚时间: $(date '+%Y-%m-%d %H:%M:%S')
回滚原因: [填写具体原因,如"首页白屏"]
回滚前版本: abc1234 (feat: update hero animation)
回滚后版本: $(git describe --tags || git log --oneline -1)
验证状态: ✅ 所有关键页面已恢复正常访问
请相关开发者尽快排查问题根因。
回滚详情:
- 操作人: $(whoami)
- 服务器: 139.155.109.62
- 域名: https://novalon.cn
- 日志位置: /tmp/rollback-log.txt
技术支持联系人:
- 值班工程师: [填写姓名] - [填写电话]
- 技术负责人: [填写姓名] - [填写电话]
EOF
echo "✅ 回滚通知已发送"
🐳 Type 2:Docker 容器级回滚(当 Type 1 不可用时)
适用场景
- 本地代码库损坏或不可用
- 需要立即恢复,来不及重新构建
- 服务器上有自动备份
步骤(全部在服务器上执行)
# SSH 到生产服务器
ssh root@139.155.109.62
# Step 1: 查看当前容器状态
docker ps | grep novalon
# 预期输出:
# CONTAINER ID IMAGE STATUS NAMES
# xxxxxxxxxx novalon-website:latest Up 2 hours novalon-nginx-secure
# Step 2: 查看可用的备份
ls -lth /home/novalon/docker-app/novalon-static_backup_* | head -5
# 预期输出:
# drwxr-xr-x 20260512_153000 ← 最新备份(1 小时前)
# drwxr-xr-x 20260512_140000 ← 之前的备份(2 小时前)
# drwxr-xr-x 20260511_180000 ← 昨天的备份
# Step 3: 选择最近的备份进行恢复
BACKUP_DIR=$(ls -dt /home/novalon/docker-app/novalon-static_backup_* | head -1)
CURRENT_DIR="/home/novalon/docker-app/novalon-static"
echo "将回滚到备份: $BACKUP_DIR"
# Step 4: 执行回滚
rm -rf "$CURRENT_DIR"
cp -r "$BACKUP_DIR" "$CURRENT_DIR"
# Step 5: 重载 Nginx 使更改生效
docker exec novalon-nginx-secure nginx -s reload
# Step 6: 验证
curl -I https://novalon.cn/ | head -1
# 预期: HTTP/2 200
echo "✅ Docker 容器级回滚完成"
🌐 Type 3:CDN 缓存清理(配合 Type 1 或 Type 2 使用)
何时需要?
- 回滚后用户仍看到旧版本的缓存内容
- 更新了 CSS/JS 文件但浏览器未加载最新版本
方法 A:强制刷新 Nginx 缓存(推荐)
# 在服务器上执行
ssh root@139.155.109.62
# 临时禁用缓存(5 分钟后记得改回来)
cat > /tmp/disable-cache.conf << 'EOF'
location / {
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate";
expires 0;
# ... 其他配置保持不变
}
EOF
# 应用配置并重载 Nginx
docker exec novalon-nginx-secure nginx -s reload
# 等待 5 分钟让所有用户的缓存过期
sleep 300
# 恢复正常缓存策略(重要!否则影响性能)
# 将原来的 nginx.conf 放回去
docker exec novalon-nginx-secure nginx -s reload
方法 B:版本化静态资源(长期方案)
如果你的项目使用了 next.config.ts 中的 assetPrefix,Next.js 会自动为静态资源添加 hash:
旧版本: /_next/static/css/abc123.css
新版本: /_next/static/css/def456.css
这样浏览器会自动请求新的 URL,无需手动清除缓存。
📞 紧急联系人列表
| 角色 | 姓名 | 电话/微信 | 职责 | 备注 |
|---|---|---|---|---|
| 值班工程师 | 待填写 | 待填写 | 执行回滚操作 | 第一响应人 |
| 技术负责人 | 待填写 | 待填写 | 决策是否回滚 | P0/P1 故障需其批准 |
| 产品负责人 | 待填写 | 待填写 | 评估业务影响 | P1/P2 故障需通知 |
| 运维支持 | 待填写 | 待填写 | 服务器/DNS 层面支持 | 当涉及基础设施问题时 |
| Sentry 告警接收人 | dev-team@novalon.cn | - | 错误监控告警 | Sentry 配置 |
📊 回滚后复盘模板(必填!)
每次回滚完成后,必须在 24 小时内填写此模板并发送到团队群:
## Novalon Website 回滚复盘报告
**基本信息**
- 回滚日期和时间:
- 发现问题时间:
- 开始回滚时间:
- 回滚完成时间:
- 总宕机时间: ___ 分钟
**问题分类**
- [ ] 代码 Bug(哪个 commit 引入的?commit hash: _____)
- [ ] 依赖兼容性问题(哪个包升级导致?包名及版本: _____)
- [ ] 配置错误(nginx/docker/env?具体是哪个配置?)
- [ ] 第三方服务故障(CDN/DNS/SSL 证书?服务商是谁?)
- [ ] 其他: _____
**问题根因分析**
(详细描述为什么会出现这个问题)
**影响范围评估**
- 影响用户数估算: 约 ___ 人
- 受影响的页面/功能:
- 是否造成数据丢失: 是/否(如果是,哪些数据?)
- 业务损失估算:
**回滚操作详情**
- 回滚类型: Type 1 (代码回滚) / Type 2 (Docker 容器级) / Type 3 (CDN 清理)
- 回滚前版本:
- 回滚后版本:
- 是否成功恢复: 是/否
- 是否需要后续修复: 是/否
**改进措施(防止再次发生)**
1.
2.
3.
**如何改进测试/CI 流程以提前发现问题**
- [ ] 补充单元测试覆盖(具体是哪个模块?)
- [ ] 增加 E2E 测试用例(具体场景是什么?)
- [ ] 在 CI Pipeline 中增加质量门禁(什么条件?)
- [ ] 接入 Sentry 错误监控(已完成 ✓)
- [ ] 完善 Code Review 流程(什么标准?)
- [ ] 其他:
**经验教训总结**
(用一两句话总结这次回滚学到了什么)
**附件**
- 截图/日志: (如有)
- 相关 Issue/PR 链接: (如有)
🔧 常见问题排查(FAQ)
Q1:回滚后网站仍然显示旧内容?
A:CDN 缓存未刷新。解决方案:
- 执行 Type 3: CDN 缓存清理
- 或等待 CDN TTL 过期(通常 1-2 小时)
- 或使用 Ctrl+Shift+R 强制刷新浏览器缓存
Q2:Git checkout 失败,提示"有未提交的更改"?
A:先暂存或丢弃这些更改:
# 查看有哪些未提交的更改
git status
# 方案 A:暂时保存(推荐)
git stash push -m "temp-save"
# 方案 B:直接丢弃(谨慎!不可逆)
git reset --hard HEAD
# 然后再执行 git checkout
Q3:npm run build:clean 构建失败?
A:可能的原因及解决方法:
- 依赖未安装完全:运行
rm -rf node_modules && npm install - TypeScript 类型错误:运行
npx tsc --noEmit查看详细错误 - ESLint 错误:运行
npm run lint查看详情 - 内存不足:增加 Node.js 内存限制
NODE_OPTIONS=--max-old-space-size=4096 npm run build:clean
Q4:SSH 连接到服务器失败?
A:检查以下几点:
- 网络连接:
ping 139.155.109.62 - SSH 服务:
ssh -v root@139.155.109.62(查看详细日志) - 防火墙:确认端口 22 未被封锁
- SSH Key:确认私钥文件权限正确 (
chmod 600 ~/.ssh/id_rsa)
Q5:回滚后发现数据库或其他动态内容丢失?
A:对于纯静态网站(你的情况),不存在这个问题!
- Novalon Website 是纯静态导出,不依赖数据库
- 所有内容都在
dist/目录中 - 回滚只是替换静态文件,不会影响任何持久化数据
⚡ 快速参考卡片(打印出来贴在工位上)
╔══════════════════════════════════════════╗
║ Novalon Website 紧急回滚速查表 ║
╠══════════════════════════════════════════╣
║ ║
║ P0 触发条件: ║
║ • 首页白屏 / 5xx 错误 ║
║ • 安全漏洞 ║
║ • 域名/SSL 问题 ║
║ ║
║ 快速回滚命令(3 步完成): ║
║ ║
║ 1. git log --oneline -10 ║
║ # 找到稳定版本的 commit ║
║ ║
║ 2. git checkout <stable-commit-hash> ║
║ # 切换到稳定版本 ║
║ ║
║ 3. ./deploy-dist.sh ║
║ # 重新构建并部署 ║
║ ║
║ 验证命令: ║
║ curl -I https://novalon.cn/ ║
║ # 预期: HTTP/2 200 ║
║ ║
║ 紧急联系人: ║
║ • 值班工程师: [姓名] - [电话] ║
║ • 技术负责人: [姓名] - [电话] ║
║ • 运维支持: [姓名] - [电话] ║
║ ║
║ 服务器信息: ║
║ IP: 139.155.109.62 ║
║ 用户: root ║
║ 域名: novalon.cn ║
║ 容器: novalon-nginx-secure ║
║ ║
║ 目标恢复时间: < 10 分钟 ║
╚══════════════════════════════════════════╝
✅ 回滚完成清单
请在回滚完成后逐项确认:
立即确认(回滚后 5 分钟内)
- 网站首页可访问,无白屏
- HTTP 状态码返回 200
- 关键页面(About, Contact, Products)可访问
- 导航栏正常工作
- SEO 元数据完整(title, description, OG tags)
- 已通知相关人员(邮件/群消息)
后续确认(回滚后 24 小时内)
- 填写回滚复盘报告
- 分析问题根因并记录
- 制定预防措施
- 更新 CI/CD Pipeline(如有必要)
- 团队内部分享经验教训
📚 相关文档链接
- 部署脚本: deploy-dist.sh
- Jenkins Pipeline: Jenkinsfile
- Sentry 监控指南: docs/sentry-setup-guide.md
- 技术栈降级指南: scripts/downgrade-stack.sh
- CONTEXT.md: CONTEXT.md(领域术语和关键决策)
💡 最后提醒:
- 保持冷静,按照步骤执行
- 每一步都要验证再继续
- 记录所有操作,方便事后复盘
- 回滚不是失败,是负责任的表现!
祝你好运!🍀