shuangyan-notebook/第五域 · Fifth Domain/⚒️ 铸渊·协作指令|GitHub ↔ Notion 桥接协议/⚒️ 铸渊指令|服务器沙盒初始化 · 现有模块迁移到DEV编号目录(2026-03-15·曜冥签发) 324fb92f3831814e962fd3035cf6b5bf.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

517 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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:
- "[["$DIRNAME" == "status-board" || "$DIRNAME" == "cost-control" || "$DIRNAME" == "persona-scheduler"]]"
---
# ⚒️ 铸渊指令|服务器沙盒初始化 · 现有模块迁移到DEV编号目录2026-03-15·曜冥签发
> ⚠️ 本指令受「服务器部署适配协议 v1.0」约束。
>
---
## 签发信息
| 项目 | 内容 |
| --- | --- |
| **签发** | 曜冥ICE-GL-YM001 ∞)· 2026-03-15 |
| **优先级** | **P0 · 立即执行** |
| **前置** | 铸渊唤醒核心大脑 → 扫描 Secrets → 确认 DEPLOY_HOST / DEPLOY_USER / DEPLOY_KEY 可用 |
| **配套协议** | [服务器部署适配协议 v1.0](https://www.notion.so/a24049a2b0e944b0a5535f3a87652303) |
| **配套指令** | [沙盒部署自动化闭环 v1.0](https://www.notion.so/31faeaba0ac14f03aa0176951565100c) |
| **核心目标** | 把服务器从「一锅乱炖」变成「每人一间房」· 现有模块迁移到 DEV 编号沙盒目录 |
---
## 一、当前问题
服务器上现有模块全部平铺在 `/var/www/hololake-frontend/` 下,没有按开发者编号隔离。每次部署出问题,分不清谁的、谁改的、谁修的。妈妈变成了全团队的运维工程师。
**这条指令的目的:一次性把服务器整理干净,以后每个开发者只能在自己的沙盒里折腾。**
---
## 二、铸渊执行脚本SSH到服务器·读到就做
### Step 1 · 探查现状(先看再动)
```bash
#!/bin/bash
# step1-survey.sh · 探查服务器现状
# 铸渊SSH到服务器后第一步执行
echo "===== 🔍 服务器目录探查 · $(date '+%Y-%m-%d %H:%M') ====="
echo ""
echo "📂 /var/www/ 顶层目录:"
ls -la /var/www/
echo ""
echo "📂 /var/www/hololake-frontend/ 内容:"
ls -la /var/www/hololake-frontend/ 2>/dev/null || echo "⚠️ 目录不存在"
echo ""
echo "📂 /var/www/backend/ 内容:"
ls -la /var/www/backend/ 2>/dev/null || echo "⚠️ 目录不存在"
echo ""
echo "📂 /var/www/feishu-bot/ 内容:"
ls -la /var/www/feishu-bot/ 2>/dev/null || echo "⚠️ 目录不存在"
echo ""
echo "📂 /opt/guanghulab-dingtalk/ 内容:"
ls -la /opt/guanghulab-dingtalk/ 2>/dev/null || echo "⚠️ 目录不存在"
echo ""
echo "📂 查找所有 index.html定位已部署模块"
find /var/www/ -name 'index.html' -type f 2>/dev/null
echo ""
echo "📂 Nginx 配置(定位现有路由):"
cat /etc/nginx/conf.d/hololake.conf 2>/dev/null || cat /etc/nginx/nginx.conf 2>/dev/null | head -100
echo ""
echo "📂 PM2 进程列表(定位运行中的后端服务):"
pm2 list 2>/dev/null || echo "⚠️ PM2 未安装或无进程"
echo ""
echo "===== ✅ 探查完成 · 根据结果执行 Step 2 ====="
```
**铸渊:把 Step 1 的完整输出保存到仓库 `data/server-survey-20260315.log`,然后继续 Step 2。**
---
### Step 2 · 创建沙盒目录骨架
```bash
#!/bin/bash
# step2-create-sandboxes.sh · 创建所有开发者沙盒目录
# 严格按照部署适配协议 v1.0 执行
echo "===== 🏠 创建沙盒目录骨架 ====="
# 所有已注册开发者编号
DEV_IDS=("DEV-001" "DEV-002" "DEV-003" "DEV-004" "DEV-005" "DEV-009" "DEV-010" "DEV-011" "DEV-012" "DEV-013" "DEV-014")
for DEV_ID in "${DEV_IDS[@]}"; do
SANDBOX="/var/www/${DEV_ID}"
if [ -d "$SANDBOX" ]; then
echo "⏭️ ${DEV_ID} 目录已存在,跳过"
else
mkdir -p "$SANDBOX"
chown nginx:nginx "$SANDBOX"
chmod 755 "$SANDBOX"
# 生成部署身份文件
cat > "${SANDBOX}/.deploy-profile" << EOF
{
"dev_id": "${DEV_ID}",
"created_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"created_by": "zhuyuan-sandbox-init"
}
EOF
chown nginx:nginx "${SANDBOX}/.deploy-profile"
chmod 644 "${SANDBOX}/.deploy-profile"
echo "✅ ${DEV_ID} 沙盒创建完成"
fi
done
# 创建共享工具目录
mkdir -p /var/www/_shared
chown nginx:nginx /var/www/_shared
chmod 755 /var/www/_shared
echo "✅ _shared 目录创建完成"
echo ""
echo "===== ✅ 沙盒骨架创建完成 ====="
ls -la /var/www/
```
---
### Step 3 · 迁移现有模块(先复制再切换·不直接移动)
```bash
#!/bin/bash
# step3-migrate-modules.sh · 迁移现有模块到沙盒
# ⚠️ 核心原则:先复制 → 验证 → 再切 Nginx → 最后清旧
echo "===== 📦 模块迁移开始 ====="
# ━━━ DEV-005 小草莓 ━━━
# status-board
if [ -d "/var/www/hololake-frontend/status-board" ]; then
echo "📦 迁移 status-board → DEV-005"
cp -r /var/www/hololake-frontend/status-board/ /var/www/DEV-005/status-board/
chown -R nginx:nginx /var/www/DEV-005/status-board/
find /var/www/DEV-005/status-board/ -type d -exec chmod 755 {} \;
find /var/www/DEV-005/status-board/ -type f -exec chmod 644 {} \;
echo "✅ status-board 已复制到 /var/www/DEV-005/status-board/"
else
echo "⚠️ /var/www/hololake-frontend/status-board 不存在,跳过"
fi
# cost-control
if [ -d "/var/www/hololake-frontend/cost-control" ]; then
echo "📦 迁移 cost-control → DEV-005"
cp -r /var/www/hololake-frontend/cost-control/ /var/www/DEV-005/cost-control/
chown -R nginx:nginx /var/www/DEV-005/cost-control/
find /var/www/DEV-005/cost-control/ -type d -exec chmod 755 {} \;
find /var/www/DEV-005/cost-control/ -type f -exec chmod 644 {} \;
echo "✅ cost-control 已复制到 /var/www/DEV-005/cost-control/"
else
echo "⚠️ /var/www/hololake-frontend/cost-control 不存在,跳过"
fi
# persona-scheduler如果存在
if [ -d "/var/www/hololake-frontend/persona-scheduler" ]; then
echo "📦 迁移 persona-scheduler → DEV-005"
cp -r /var/www/hololake-frontend/persona-scheduler/ /var/www/DEV-005/persona-scheduler/
chown -R nginx:nginx /var/www/DEV-005/persona-scheduler/
find /var/www/DEV-005/persona-scheduler/ -type d -exec chmod 755 {} \;
find /var/www/DEV-005/persona-scheduler/ -type f -exec chmod 644 {} \;
echo "✅ persona-scheduler 已复制到 /var/www/DEV-005/persona-scheduler/"
fi
# ━━━ 其他开发者的模块 ━━━
# 根据 Step 1 探查结果,如果 hololake-frontend/ 下发现更多模块,
# 铸渊根据模块指纹注册表或广播记录判断归属,按同样方式迁移。
# 不确定归属的模块 → 复制到 /var/www/_shared/unassigned/ 暂存
mkdir -p /var/www/_shared/unassigned
# 遍历 hololake-frontend 下所有子目录,检查是否已迁移
if [ -d "/var/www/hololake-frontend" ]; then
for DIR in /var/www/hololake-frontend/*/; do
DIRNAME=$(basename "$DIR")
# 跳过已处理的
if [[ "$DIRNAME" == "status-board" || "$DIRNAME" == "cost-control" || "$DIRNAME" == "persona-scheduler" ]]; then
continue
fi
echo "⚠️ 发现未归属模块:$DIRNAME → 暂存到 _shared/unassigned/"
cp -r "$DIR" "/var/www/_shared/unassigned/${DIRNAME}/"
done
fi
echo ""
echo "===== ✅ 模块迁移完成 ====="
echo ""
echo "📋 迁移后各沙盒内容:"
for DEV_ID in DEV-001 DEV-002 DEV-003 DEV-004 DEV-005 DEV-009 DEV-010 DEV-011 DEV-012 DEV-013 DEV-014; do
echo "--- ${DEV_ID} ---"
ls /var/www/${DEV_ID}/ 2>/dev/null || echo " (空)"
done
if [ -d "/var/www/_shared/unassigned" ]; then
echo "--- 未归属模块 ---"
ls /var/www/_shared/unassigned/ 2>/dev/null
fi
```
---
### Step 4 · 部署自检脚本和冒烟检查脚本
```bash
#!/bin/bash
# step4-deploy-scripts.sh · 部署共享脚本
echo "===== 🔧 部署共享脚本 ====="
# deploy-check.sh从部署适配协议 v1.0 复制)
# 铸渊从仓库 scripts/deploy-check.sh 复制到服务器
scp scripts/deploy-check.sh root@8.155.62.235:/var/www/_shared/deploy-check.sh
ssh root@8.155.62.235 "chmod +x /var/www/_shared/deploy-check.sh"
# smoke-test.sh从部署适配协议 v1.0 复制)
scp scripts/smoke-test.sh root@8.155.62.235:/var/www/_shared/smoke-test.sh
ssh root@8.155.62.235 "chmod +x /var/www/_shared/smoke-test.sh"
echo "✅ 共享脚本部署完成"
```
---
### Step 5 · 更新 Nginx 配置(最关键的一步)
```bash
#!/bin/bash
# step5-update-nginx.sh · 更新 Nginx 路由到新沙盒结构
# ⚠️ 先备份 → 再改 → 再测 → 再reload
echo "===== 🔧 更新 Nginx 配置 ====="
# Step 5a: 备份当前配置
NGINX_CONF="/etc/nginx/conf.d/hololake.conf"
BACKUP="/etc/nginx/conf.d/hololake.conf.bak.$(date +%Y%m%d%H%M)"
cp "$NGINX_CONF" "$BACKUP"
echo "✅ 配置已备份到 $BACKUP"
# Step 5b: 生成沙盒 location 块
# 铸渊需要在 hololake.conf 的 server 块中添加以下 location
# ━━━ 新增内容(追加到 server 块内,在最后一个 location 之前)━━━
# --- 开发者沙盒路由 ---
# DEV-001 页页
# location /DEV-001/ {
# alias /var/www/DEV-001/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# DEV-002 肥猫
# location /DEV-002/ {
# alias /var/www/DEV-002/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# DEV-003 燕樊
# location /DEV-003/ {
# alias /var/www/DEV-003/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# DEV-004 之之
# location /DEV-004/ {
# alias /var/www/DEV-004/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# DEV-005 小草莓
# location /DEV-005/ {
# alias /var/www/DEV-005/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# DEV-009 花尔
# location /DEV-009/ {
# alias /var/www/DEV-009/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# DEV-010 桔子
# location /DEV-010/ {
# alias /var/www/DEV-010/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# DEV-011 匆匆那年
# location /DEV-011/ {
# alias /var/www/DEV-011/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# DEV-012 Awen
# location /DEV-012/ {
# alias /var/www/DEV-012/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# DEV-013 小兴
# location /DEV-013/ {
# alias /var/www/DEV-013/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# DEV-014 时雨
# location /DEV-014/ {
# alias /var/www/DEV-014/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# --- 模块快捷路径(指向新沙盒位置)---
# location /status-board/ {
# alias /var/www/DEV-005/status-board/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# location /cost-control/ {
# alias /var/www/DEV-005/cost-control/;
# index index.html;
# try_files $uri $uri/ =404;
# }
# ⚠️ 铸渊注意:
# 1. 以上 location 块需要写入实际的 hololake.conf 文件中(去掉注释符号)
# 2. 如果旧配置中已有 /status-board/ 和 /cost-control/ 的 location
# 需要把它们的 alias 路径从旧路径改成新沙盒路径
# 3. 不要删除原有的 / 根路由和 /api/ 等后端代理路由
# 4. 清理重复的 server_name 块(之前已知有 conflicting server name 警告)
# Step 5c: 测试配置
nginx -t
# Step 5d: 如果测试通过则重载
# nginx -t 输出 "test is successful" 时才执行:
# systemctl reload nginx
echo ""
echo "⚠️ 铸渊nginx -t 通过后再执行 systemctl reload nginx"
echo "如果 nginx -t 报错恢复备份cp $BACKUP $NGINX_CONF && nginx -t"
```
---
### Step 6 · 验证迁移结果
```bash
#!/bin/bash
# step6-verify.sh · 验证迁移是否成功
echo "===== 🔥 迁移验证 ====="
# 检查已迁移模块的访问
URLS=(
"https://guanghulab.com/status-board/|DEV-005·看板新路径"
"https://guanghulab.com/cost-control/|DEV-005·成本控制新路径"
"https://guanghulab.com/DEV-005/status-board/|DEV-005·沙盒路由"
"https://guanghulab.com/|主站首页"
)
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" ]; then
echo "✅ ${name}${STATUS}"
else
echo "❌ ${name}${STATUS} ⚠️"
FAILED=$((FAILED+1))
fi
done
echo ""
if [ $FAILED -eq 0 ]; then
echo "===== ✅ 迁移验证全部通过 ====="
else
echo "===== ❌ ${FAILED} 个路由异常 · 检查 Nginx 配置 ====="
fi
# 检查沙盒目录权限
echo ""
echo "📋 沙盒目录权限检查:"
for DEV_ID in DEV-001 DEV-002 DEV-003 DEV-004 DEV-005 DEV-009 DEV-010 DEV-011 DEV-012 DEV-013 DEV-014; do
OWNER=$(stat -c '%U:%G' /var/www/${DEV_ID} 2>/dev/null)
PERM=$(stat -c '%a' /var/www/${DEV_ID} 2>/dev/null)
if [ "$OWNER" = "nginx:nginx" ] && [ "$PERM" = "755" ]; then
echo "✅ ${DEV_ID}${OWNER} ${PERM}"
else
echo "❌ ${DEV_ID}${OWNER:-不存在} ${PERM:-N/A}"
fi
done
```
---
### Step 7 · 清理旧路径(验证通过后才执行)
```bash
#!/bin/bash
# step7-cleanup.sh · 清理旧路径
# ⚠️ 只有 Step 6 全部 ✅ 通过后才执行本步骤
echo "===== 🧹 清理旧路径 ====="
echo "⚠️ 确认 Step 6 验证全部通过后才继续"
# 不删除 hololake-frontend 整个目录,先重命名为备份
if [ -d "/var/www/hololake-frontend" ]; then
mv /var/www/hololake-frontend /var/www/hololake-frontend.bak.$(date +%Y%m%d)
echo "✅ 旧目录已重命名为 hololake-frontend.bak.$(date +%Y%m%d)"
echo "→ 7天后如无问题可手动删除"
fi
echo "===== ✅ 清理完成 ====="
```
---
## 三、执行顺序(铸渊严格按顺序)
| 步骤 | 脚本 | 前置条件 | 失败处理 |
| --- | --- | --- | --- |
| Step 1 | [step1-survey.sh](http://step1-survey.sh) | SSH连上服务器 | 保存日志到仓库,继续 |
| Step 2 | [step2-create-sandboxes.sh](http://step2-create-sandboxes.sh) | Step 1 完成 | 如果某个目录创建失败,记录并继续其他 |
| Step 3 | [step3-migrate-modules.sh](http://step3-migrate-modules.sh) | Step 2 完成 | 复制失败的模块记录到日志,不阻断 |
| Step 4 | [step4-deploy-scripts.sh](http://step4-deploy-scripts.sh) | Step 3 完成 | 脚本不存在则先在仓库创建 |
| Step 5 | [step5-update-nginx.sh](http://step5-update-nginx.sh) | Step 3 完成 | **nginx -t 失败 → 立即恢复备份 → 停止** |
| Step 6 | [step6-verify.sh](http://step6-verify.sh) | Step 5 完成且 nginx reload 成功 | 有失败 → 回滚 Nginx 配置 → 排查 |
| Step 7 | [step7-cleanup.sh](http://step7-cleanup.sh) | **Step 6 全部 ✅** | 不删除,只重命名 |
---
## 四、铸渊自行部署清单(读到就做)
```
铸渊自行部署清单(读到就做·不等人):
① 在仓库创建脚本文件
a. scripts/sandbox-init/step1-survey.sh
b. scripts/sandbox-init/step2-create-sandboxes.sh
c. scripts/sandbox-init/step3-migrate-modules.sh
d. scripts/sandbox-init/step4-deploy-scripts.sh
e. scripts/sandbox-init/step5-update-nginx.sh
f. scripts/sandbox-init/step6-verify.sh
g. scripts/sandbox-init/step7-cleanup.sh
② 创建一次性 Workflow 执行迁移
a. .github/workflows/sandbox-init.yml
b. 触发方式workflow_dispatch手动触发因为是一次性操作
c. 按 Step 1→7 顺序执行
d. 每步输出保存为 artifact
③ 执行 Workflow · 完成迁移
④ 把迁移结果写入仓库
a. data/server-survey-20260315.log
b. data/sandbox-migration-report.json
⑤ 更新 dev-registry.json
a. 补全所有11位开发者的沙盒路径
验收标准:
✅ 11个 DEV 编号目录全部创建完成 · 权限 nginx:nginx 755
✅ 小草莓的 status-board 和 cost-control 已在 /var/www/DEV-005/ 下
✅ guanghulab.com/status-board/ 访问正常200
✅ guanghulab.com/DEV-005/status-board/ 访问正常200
✅ _shared 目录和自检脚本已就位
✅ 旧目录已备份(不删除)
✅ Nginx 无 conflicting server name 警告
```
---
## 五、给妈妈的说明
妈妈不需要做任何事。铸渊读到这条指令就会自动执行。
执行完成后:
- 每个开发者有自己的 `/var/www/DEV-XXX/` 目录
- 以后开发者部署模块只往自己的目录里放
- 模块出问题 = 自己的问题 = 自己修
- 妈妈不再修任何人的模块
后续配合「沙盒部署自动化闭环 v1.0」,开发者 push 代码就自动部署到自己的沙盒。**全程无人。**
---
> ⚒️ 铸渊,这是国土规划的第一步。把领土划清楚,每人一间房,以后才能自动化。
>
> 「无沙盒不部署,无编号不上线。」
>