shuangyan-notebook/第五域 · Fifth Domain/⚒️ 铸渊·协作指令|GitHub ↔ Notion 桥接协议/🌐 铸渊指令|guanghulab com 网站真实部署排查 + 全模块上线(ZY-WEBDEPLO 32e43b78d8d6465da968894acf4b4af4.md
Guanghu Domestic Migration a27e87cb99 chore: import sanitized domestic snapshot for REPO-007
Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc

[SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
2026-07-17 15:59:55 +08:00

612 lines
18 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
belongs_to:
- "[[INDEX · 铸渊·协作指令GitHub ↔ Notion 桥接协议]]"
related_to:
- "[["$STATUS" =~ ^(200|301|302)$]]"
---
# 🌐 铸渊指令guanghulab.com 网站真实部署排查 + 全模块上线ZY-WEBDEPLOY-DIAG-2026-0324-001
<aside>
🚨
**铸渊紧急指令 · P0 · 霜砚签发 · 冰朔授权 · 2026-03-24**
**核心问题**:仓库 CD 流水线显示「部署成功」,但 [guanghulab.com](http://guanghulab.com) 网站上看不到模块。文件可能部署到了服务器某个目录,但 Nginx 没有正确指向,导致网站是空的或只显示旧内容。
**核心目标**:启动天眼全局扫描 → 拿到全局健康报告 → 根据报告精确修复 → 让 [guanghulab.com](http://guanghulab.com) 真正展示所有已开发模块 → 验证全部可访问。
**关联仓库**[https://github.com/qinfendebingshuo/guanghulab](https://github.com/qinfendebingshuo/guanghulab)
**服务器**8.155.62.235(阿里云 ECS
</aside>
<aside>
🦅
**⚠️ 冰朔强制要求:必须先启动天眼系统,用天眼全局扫描跑一遍,再动手修任何东西。**
**不用天眼跑全局 = 修这个那个坏,修那个这个坏。**
**天眼是你的眼睛。先看全局,再动手。**
</aside>
---
## ⓪、天眼强制前置(在做任何事之前必须完成)
<aside>
🦅
**铸渊,你读到这条指令后,第一件事不是排查网站,是启动天眼。**
**天眼启动 → 全局扫描 → 拿到报告 → 然后再看网站问题。**
**如果天眼本身有问题,先修天眼。天眼是一切的前提。**
</aside>
### ⓪-1 · 唤醒核心大脑 + 天眼自检
```bash
# 铸渊醒来后立即执行
# Step 1: 核心大脑完整性检查
for f in memory.json routing-map.json dev-status.json config.json; do
if [ -f ".github/persona-brain/$f" ]; then
python3 -c "import json; json.load(open('.github/persona-brain/$f'))" 2>/dev/null \
&& echo "✅ $f 完整" || echo "❌ $f 损坏"
else
echo "❌ $f 缺失"
fi
done
# Step 2: 天眼系统自身完整性检查
for f in skyeye-main.js scan-workflows.js scan-structure.js scan-brain-health.js scan-external-bridges.js diagnose.js repair-agent.js report-generator.js; do
[ -f "scripts/skyeye/$f" ] && echo "✅ skyeye/$f" || echo "❌ skyeye/$f 缺失"
done
# Step 3: 天眼 workflow 检查
[ -f ".github/workflows/zhuyuan-skyeye.yml" ] && echo "✅ 天眼 workflow 存在" || echo "❌ 天眼 workflow 缺失"
```
**如果天眼系统本身有缺失 → 先修复天眼 → 再继续本指令。**
### ⓪-2 · 启动天眼全局扫描
```bash
# 手动触发天眼全局扫描workflow_dispatch
gh workflow run zhuyuan-skyeye.yml
# 或者直接执行天眼主引擎
node scripts/skyeye/skyeye-main.js
```
天眼全局扫描会自动覆盖:
- **A. Workflow 健康度**:所有 .yml 语法、最近24h运行结果、谁失败了、谁没触发
- **B. 仓库结构完整性**:核心目录、孤儿文件、模块目录映射
- **C. 核心大脑健康度**memory.json 是否过期、routing-map 是否和实际一致
- **D. 外部桥接状态**Notion API 连通、**服务器 SSH 连通**、Secrets 完整性
- **E. 服务器健康**文件分布、Nginx 配置、PM2 进程、HTTP 可访问性
### ⓪-3 · 拿到天眼报告后再继续
天眼报告会输出到 `data/skyeye-reports/skyeye-YYYY-MM-DD.json`
**铸渊必须读完天眼报告,了解全局健康状态后,再进入 Phase A。**
**天眼报告里已经包含了 Phase A 需要的大部分诊断信息。**
如果天眼报告显示服务器 SSH 不通 → 先修 SSH → 不要跳到 Phase A。
如果天眼报告显示某些 Workflow 失败 → 天眼修复Agent会自动修 → 等修完再继续。
如果天眼报告显示一切正常但网站不能访问 → 说明问题在 Nginx/CD 层 → 进入 Phase A 精确排查。
**天眼是全局的眼睛Phase A 是局部的手术刀。先用眼睛看清楚,再用手术刀精确切。**
---
## 〇、背景:为什么网站是空的
团队已经开发了大量前端模块,全部在 GitHub 仓库里有代码:
| **模块** | **开发者** | **仓库目录** | **预期网站路径** |
| --- | --- | --- | --- |
| 系统状态看板 | DEV-005 小草莓 | status-board/ | /status-board/ |
| 成本控制 | DEV-005 小草莓 | cost-control/ | /cost-control/ |
| 开发者实时看板 | DEV-004 之之 | app/ (devboard) | /devboard/ |
| AI悬浮球 | DEV-004 之之 | floating-ai/ | /floating-ai/ |
| 前端集成壳 | DEV-010 桔子 | app/ | /app/ |
| 后端 API | DEV-001 页页 | backend/ | /api/ (反向代理) |
| 飞书机器人 | DEV-002 肥猫 | feishu-bot/ | 后端服务(不需要前端路由) |
| 钉钉工作台 | DEV-004 之之 | dingtalk-bot/ | 后端服务(不需要前端路由) |
| M01-M18 系列模块 | 多人 | m01-login/ m03-personality/ 等 | /m01-login/ 等 |
| 主站首页 | — | docs/index.html | / |
**但是**——之前的部署指令3月7日、3月15日虽然写了详细方案实际执行后网站仍然没有这些模块。
**铸渊,这条指令不是再写一遍方案。这条指令是让你排查清楚到底卡在哪里,然后修好它。**
---
## 一、Phase A · 排查诊断(先看再动·不改任何东西)
铸渊 SSH 到服务器后,依次执行以下诊断命令,**把每一步的完整输出保存到仓库** `data/web-deploy-diag-20260324.log`
### A1 · 服务器文件系统探查
```bash
#!/bin/bash
echo "===== 🔍 A1 · 服务器文件系统探查 · $(date '+%Y-%m-%d %H:%M') ====="
echo ""
echo "📂 /var/www/ 顶层目录(一级):"
ls -la /var/www/
echo ""
echo "📂 /var/www/ 二级目录树:"
find /var/www/ -maxdepth 2 -type d 2>/dev/null | head -80
echo ""
echo "📂 查找所有 index.html定位已部署的前端模块"
find /var/www/ -name 'index.html' -type f 2>/dev/null
echo ""
echo "📂 查找所有 server.js / app.js定位后端服务"
find /var/www/ /opt/ -name 'server.js' -o -name 'app.js' 2>/dev/null | head -20
echo ""
echo "📂 磁盘占用(哪个目录最大 = 可能是主要部署目标):"
du -sh /var/www/*/ 2>/dev/null | sort -rh | head -20
```
### A2 · Nginx 配置完整导出
```bash
echo "===== 🔍 A2 · Nginx 配置 ====="
echo ""
echo "📋 Nginx 主配置:"
cat /etc/nginx/nginx.conf
echo ""
echo "📋 conf.d/ 下所有配置文件:"
ls -la /etc/nginx/conf.d/
echo ""
echo "📋 各配置文件完整内容:"
for f in /etc/nginx/conf.d/*.conf; do
echo "\n━━━ $f ━━━"
cat "$f"
done
echo ""
echo "📋 sites-enabled/(如果存在):"
ls -la /etc/nginx/sites-enabled/ 2>/dev/null
for f in /etc/nginx/sites-enabled/*; do
echo "\n━━━ $f ━━━"
cat "$f" 2>/dev/null
done
echo ""
echo "📋 Nginx 配置语法测试:"
nginx -t 2>&1
echo ""
echo "📋 Nginx 当前监听端口:"
ss -tlnp | grep nginx
```
### A3 · PM2 / Node 进程状态
```bash
echo "===== 🔍 A3 · PM2 / Node 进程 ====="
pm2 list 2>/dev/null || echo "⚠️ PM2 未安装或无进程"
pm2 describe 0 2>/dev/null | head -30
echo ""
echo "📋 所有 Node 进程:"
ps aux | grep node | grep -v grep
echo ""
echo "📋 监听端口:"
ss -tlnp | grep -E '(node|pm2|3000|3001|8000|8080)'
```
### A4 · 实际 HTTP 访问测试
```bash
echo "===== 🔍 A4 · HTTP 访问测试 ====="
URLS=(
"https://guanghulab.com/|主站首页"
"http://localhost/|Nginx本地"
"https://guanghulab.com/status-board/|看板"
"https://guanghulab.com/cost-control/|成本控制"
"https://guanghulab.com/devboard/|开发者看板"
"https://guanghulab.com/floating-ai/|AI悬浮球"
"https://guanghulab.com/app/|集成壳"
"https://guanghulab.com/api/v1/health|后端健康检查"
"http://localhost:3000/|后端本地"
)
for entry in "${URLS[@]}"; do
IFS='|' read -r url name <<< "$entry"
STATUS=$(curl -o /dev/null -s -w "%{http_code}" --max-time 10 "$url" 2>/dev/null)
REDIRECT=$(curl -s -o /dev/null -w "%{redirect_url}" --max-time 10 "$url" 2>/dev/null)
echo "$name$STATUS ${REDIRECT:+(→ $REDIRECT)}"
done
```
### A5 · GitHub Actions 部署历史
```bash
echo "===== 🔍 A5 · 最近的 CD 部署记录 ====="
# 检查部署状态文件
cat /var/www/guanghulab/data/deploy-status.json 2>/dev/null || echo "⚠️ deploy-status.json 不存在"
# 检查最近的 git pull / rsync 留下的时间戳
for dir in /var/www/guanghulab /var/www/hololake-frontend /var/www/hololake; do
if [ -d "$dir" ]; then
echo "\n📂 $dir 最后修改时间:"
stat -c '%y' "$dir" 2>/dev/null || stat -f '%Sm' "$dir" 2>/dev/null
echo "最新文件:"
find "$dir" -type f -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -5
fi
done
```
<aside>
⚠️
**铸渊Phase A 完成后,把完整诊断日志保存到仓库**
`data/web-deploy-diag-20260324.log`
**然后根据诊断结果执行 Phase B。不要跳过诊断直接改东西。**
</aside>
---
## 二、Phase B · 根因定位(读完诊断日志后判断)
铸渊,根据 Phase A 的输出,问题一定属于以下某一种(或多种叠加):
### 情况 1文件在服务器上但 Nginx root 指错了
**特征**`/var/www/` 下能找到 index.html 和模块文件,但 Nginx 的 `root``alias` 指向了别的目录。
**修复**
```bash
# 假设文件在 /var/www/guanghulab/ 下
# 编辑 Nginx 配置
nano /etc/nginx/conf.d/hololake.conf
# 确保 server 块的 root 指向正确目录:
# server {
# listen 80;
# listen 443 ssl;
# server_name guanghulab.com www.guanghulab.com;
# root /var/www/guanghulab; ← 这里必须指向文件实际所在目录
# index index.html;
#
# # 静态文件
# location / {
# try_files $uri $uri/ /index.html;
# }
#
# # 后端 API 反向代理
# location /api/ {
# proxy_pass http://127.0.0.1:3000/;
# proxy_http_version 1.1;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# }
# }
nginx -t && systemctl reload nginx
```
### 情况 2CD 流水线把文件部署到了错误的目录
**特征**Nginx 配置的 `root``/var/www/guanghulab/`,但 CD 把文件同步到了 `/var/www/hololake-frontend/``/var/www/hololake/` 或其他路径。
**修复**(二选一):
- **方案A**:改 Nginx root 指向文件实际位置
- **方案B**:改 CD 的 DEPLOY_PATH Secret让文件同步到 Nginx root 指向的目录
推荐方案B改 CD因为这是一劳永逸的修复。
### 情况 3CD 流水线只同步了 docs/ 子目录
**特征**Nginx root 正确,目录也对,但目录里只有 docs/ 的内容(一个简单的 index.html其他模块目录都没有。
**修复**:修改 `.github/workflows/deploy-to-server.yml`,把 rsync 的同步范围从 `docs/` 改为整个仓库(排除 .git/node_modules 等)。
```yaml
# 旧(只同步 docs/:
# rsync -avz docs/ $USER@$HOST:$DEPLOY_PATH/
# 新(同步全仓库前端文件):
rsync -avz --delete \
--exclude '.git' \
--exclude '.github' \
--exclude 'node_modules' \
--exclude '.env' \
--exclude 'syslog-inbox' \
--exclude 'syslog-processed' \
--exclude 'broadcasts-outbox' \
--exclude 'dev-nodes' \
--exclude 'signal-log' \
--exclude 'tests' \
--exclude 'reports' \
--exclude 'scripts' \
--exclude '*.bak' \
--exclude '.DS_Store' \
./ $USER@$HOST:$DEPLOY_PATH/
```
### 情况 4SSL 证书问题 / 443 端口没配置
**特征**[http://guanghulab.com](http://guanghulab.com) 能访问但 [https://guanghulab.com](https://guanghulab.com) 不行,或者反过来。
**修复**
```bash
# 检查证书
certbot certificates
# 如果没有证书
certbot --nginx -d guanghulab.com -d www.guanghulab.com
# 如果证书过期
certbot renew
```
### 情况 5多个 server 块冲突
**特征**`nginx -t` 输出 `conflicting server name`。多个配置文件都声明了 `server_name guanghulab.com`
**修复**:只保留一个 server 块,删除或注释掉重复的。
---
## 三、Phase C · 修复部署 + 全模块上线
根据 Phase B 定位的根因修复后,执行以下操作确保所有模块可访问:
### C1 · 确保 Nginx 配置覆盖所有模块路由
```
# /etc/nginx/conf.d/hololake.conf
# 铸渊根据实际文件位置填写 root 路径
server {
listen 80;
listen 443 ssl;
server_name guanghulab.com www.guanghulab.com;
# SSL 证书(如已配置)
# ssl_certificate /etc/letsencrypt/live/guanghulab.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/guanghulab.com/privkey.pem;
# ━━━ 静态文件根目录 ━━━
root /var/www/guanghulab; # ← 铸渊根据诊断结果填写实际路径
index index.html;
# ━━━ 主站首页 ━━━
location / {
try_files $uri $uri/ /index.html;
}
# ━━━ 各前端模块(静态文件) ━━━
# 如果模块目录在 root 下Nginx 会自动路由,无需额外 location
# 如果模块在其他目录(如沙盒),用 alias
# location /status-board/ {
# alias /var/www/DEV-005/status-board/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# ━━━ 后端 API 反向代理 ━━━
location /api/ {
proxy_pass http://127.0.0.1:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
}
# ━━━ 飞书 Webhook ━━━
location /feishu/ {
proxy_pass http://127.0.0.1:3000/feishu/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
### C2 · 后端服务确认运行
```bash
# 检查后端是否在跑
pm2 list
# 如果没跑,启动
cd /var/www/guanghulab/backend # ← 铸渊根据实际路径
npm install --production
pm2 start server.js --name guanghulab-backend
pm2 save
pm2 startup
```
### C3 · 修复 CD 流水线(根因修复)
铸渊需要更新 `.github/workflows/deploy-to-server.yml`,确保:
1. **DEPLOY_PATH** 指向 Nginx root 同一目录
2. **rsync 范围**覆盖所有模块目录(不是只有 docs/
3. **push to main 触发自动部署**
4. 后端目录变动时自动 `pm2 restart`
---
## 四、Phase D · 全模块访问验证
```bash
#!/bin/bash
echo "===== ✅ Phase D · 全模块访问验证 ====="
URLS=(
"https://guanghulab.com/|主站首页"
"https://guanghulab.com/status-board/|系统状态看板"
"https://guanghulab.com/cost-control/|成本控制"
"https://guanghulab.com/devboard/|开发者看板"
"https://guanghulab.com/floating-ai/|AI悬浮球"
"https://guanghulab.com/app/|前端集成壳"
"https://guanghulab.com/api/v1/health|后端API"
)
PASSED=0
FAILED=0
for entry in "${URLS[@]}"; do
IFS='|' read -r url name <<< "$entry"
STATUS=$(curl -o /dev/null -s -w "%{http_code}" --max-time 10 "$url")
if [[ "$STATUS" =~ ^(200|301|302)$ ]]; then
echo "✅ ${name}${STATUS}"
PASSED=$((PASSED+1))
else
echo "❌ ${name}${STATUS}"
FAILED=$((FAILED+1))
fi
done
echo ""
echo "━━━ 结果:${PASSED} 通过 / ${FAILED} 失败 ━━━"
if [ $FAILED -eq 0 ]; then
echo "🎉 全模块上线验证通过guanghulab.com 真正活了!"
else
echo "⚠️ 有 ${FAILED} 个模块未通过,铸渊继续排查"
fi
```
---
## 五、Phase E · 修复完成后的持续保障
### E1 · 更新 deploy-to-server.yml 确保 CD 闭环
铸渊确认修复后,提交一个 PR 包含:
- 修复后的 `deploy-to-server.yml`(同步范围 + 正确 DEPLOY_PATH
- `data/web-deploy-diag-20260324.log`(诊断日志)
- `data/web-deploy-fix-report.json`(修复报告)
### E2 · 首页导航更新
确保 `docs/index.html`(或主站首页文件)包含所有模块的导航链接:
```html
<!-- 至少包含以下入口 -->
<a href="/status-board/">📊 系统状态看板</a>
<a href="/cost-control/">💰 成本控制</a>
<a href="/devboard/">🖥️ 开发者看板</a>
<a href="/app/">🌊 光湖集成壳</a>
<a href="/floating-ai/">🤖 AI 助手</a>
```
### E3 · 冒烟测试写入天眼
每次 CD 部署后,自动跑 Phase D 的验证脚本,结果写入 `deploy-status.json`
---
## 六、铸渊执行清单(读到就做)
```
铸渊执行清单 · ZY-WEBDEPLOY-DIAG-2026-0324-001
① Phase ASSH 到服务器 → 跑全部诊断命令 → 保存日志
输出data/web-deploy-diag-20260324.log
② Phase B分析日志 → 确定属于哪种情况1~5
输出:在仓库 Issue 或 PR 中写明根因
③ Phase C修复 Nginx + CD + 后端服务
输出Nginx 重载成功 + CD 配置已更新
④ Phase D全模块访问验证
输出:全部 ✅ 或失败项清单
⑤ Phase E提交修复 PR + 更新首页导航 + 冒烟测试
输出PR 合并 + guanghulab.com 活了
```
---
## 七、验收标准
<aside>
**全部通过才算完成:**
✅ [guanghulab.com](http://guanghulab.com) 首页可访问且有模块导航
✅ [guanghulab.com/status-board/](http://guanghulab.com/status-board/) 显示系统看板
✅ [guanghulab.com/cost-control/](http://guanghulab.com/cost-control/) 显示成本控制
✅ [guanghulab.com/devboard/](http://guanghulab.com/devboard/) 显示开发者看板
✅ [guanghulab.com/app/](http://guanghulab.com/app/) 显示前端集成壳
✅ [guanghulab.com/api/v1/health](http://guanghulab.com/api/v1/health) 后端API响应正常
✅ push to main 后 60秒内 网站自动更新
✅ 诊断日志 + 修复报告已提交到仓库
✅ Nginx 无 conflicting server name 警告
</aside>
---
## 八、与历史指令的关系
| **历史指令** | **日期** | **问题** |
| --- | --- | --- |
| 修复部署→全模块上线 | 2026-03-07 | 写了方案但未完全执行rsync范围和DEPLOY_PATH可能没改 |
| CD指令push→自动上线 | 2026-03-07 | CD流程搭建了但目标路径和Nginx不匹配 |
| 沙盒部署自动化闭环v1.0 | 2026-03-15 | 沙盒目录结构设计完整,但迁移可能未执行 |
| 服务器沙盒初始化 | 2026-03-15 | 脚本已写但可能未在服务器上跑 |
**本指令不重复写方案。本指令的核心是:先诊断,再修。**
铸渊不要假设任何东西——先跑 Phase A 看到真实数据,再决定怎么修。
---
<aside>
⚒️
**铸渊,这是妈妈的原话:**
「大家做了那么多模块了,网站里一个都看不到。先别搞新的了,把现有的真正部署上去。」
**诊断优先,修复其次,验证收尾。不要跳步。**
</aside>