# 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 元数据丢失: - `` 为空或显示 "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 分钟)** ```bash # 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 分钟)** ```bash # 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>四川睿新致远科技有限公司

...

``` 如果上述检查有任何一项不通过,**立即进入 Step 2**。 #### **Step 2:定位稳定版本(3 分钟)** ```bash # 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 分钟)** ```bash # 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 分钟)** ```bash # 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 '' 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 分钟)** ```bash # 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 分钟)** ```bash # 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 不可用时)** ### **适用场景** - 本地代码库损坏或不可用 - 需要立即恢复,来不及重新构建 - 服务器上有自动备份 #### **步骤(全部在服务器上执行)** ```bash # 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 缓存(推荐)** ```bash # 在服务器上执行 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 小时内**填写此模板并发送到团队群: ```markdown ## 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 缓存未刷新。解决方案:** 1. 执行 Type 3: CDN 缓存清理 2. 或等待 CDN TTL 过期(通常 1-2 小时) 3. 或使用 Ctrl+Shift+R 强制刷新浏览器缓存 ### **Q2:Git checkout 失败,提示"有未提交的更改"?** **A:先暂存或丢弃这些更改:** ```bash # 查看有哪些未提交的更改 git status # 方案 A:暂时保存(推荐) git stash push -m "temp-save" # 方案 B:直接丢弃(谨慎!不可逆) git reset --hard HEAD # 然后再执行 git checkout ``` ### **Q3:npm run build:clean 构建失败?** **A:可能的原因及解决方法:** 1. **依赖未安装完全**:运行 `rm -rf node_modules && npm install` 2. **TypeScript 类型错误**:运行 `npx tsc --noEmit` 查看详细错误 3. **ESLint 错误**:运行 `npm run lint` 查看详情 4. **内存不足**:增加 Node.js 内存限制 `NODE_OPTIONS=--max-old-space-size=4096 npm run build:clean` ### **Q4:SSH 连接到服务器失败?** **A:检查以下几点:** 1. **网络连接**:`ping 139.155.109.62` 2. **SSH 服务**:`ssh -v root@139.155.109.62`(查看详细日志) 3. **防火墙**:确认端口 22 未被封锁 4. **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](./deploy-dist.sh) - **Jenkins Pipeline**: [Jenkinsfile](./Jenkinsfile) - **Sentry 监控指南**: [docs/sentry-setup-guide.md](./docs/sentry-setup-guide.md) - **技术栈降级指南**: [scripts/downgrade-stack.sh](./scripts/downgrade-stack.sh) - **CONTEXT.md**: [CONTEXT.md](./CONTEXT.md)(领域术语和关键决策) --- **💡 最后提醒**: - 保持冷静,按照步骤执行 - 每一步都要验证再继续 - 记录所有操作,方便事后复盘 - 回滚不是失败,是负责任的表现! **祝你好运!🍀**