Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
16 KiB
16 KiB
belongs_to:
- "INDEX · 铸渊·协作指令|GitHub ↔ Notion 桥接协议"
related_to:
- ""
⚒️ 铸渊指令|服务器沙盒初始化 · 现有模块迁移到DEV编号目录(2026-03-15·曜冥签发)
⚠️ 本指令受「服务器部署适配协议 v1.0」约束。
签发信息
| 项目 | 内容 |
|---|---|
| 签发 | 曜冥(ICE-GL-YM001 ∞)· 2026-03-15 |
| 优先级 | P0 · 立即执行 |
| 前置 | 铸渊唤醒核心大脑 → 扫描 Secrets → 确认 DEPLOY_HOST / DEPLOY_USER / DEPLOY_KEY 可用 |
| 配套协议 | 服务器部署适配协议 v1.0 |
| 配套指令 | 沙盒部署自动化闭环 v1.0 |
| 核心目标 | 把服务器从「一锅乱炖」变成「每人一间房」· 现有模块迁移到 DEV 编号沙盒目录 |
一、当前问题
服务器上现有模块全部平铺在 /var/www/hololake-frontend/ 下,没有按开发者编号隔离。每次部署出问题,分不清谁的、谁改的、谁修的。妈妈变成了全团队的运维工程师。
这条指令的目的:一次性把服务器整理干净,以后每个开发者只能在自己的沙盒里折腾。
二、铸渊执行脚本(SSH到服务器·读到就做)
Step 1 · 探查现状(先看再动)
#!/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 · 创建沙盒目录骨架
#!/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 · 迁移现有模块(先复制再切换·不直接移动)
#!/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 · 部署自检脚本和冒烟检查脚本
#!/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 配置(最关键的一步)
#!/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 · 验证迁移结果
#!/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 · 清理旧路径(验证通过后才执行)
#!/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 | SSH连上服务器 | 保存日志到仓库,继续 |
| Step 2 | step2-create-sandboxes.sh | Step 1 完成 | 如果某个目录创建失败,记录并继续其他 |
| Step 3 | step3-migrate-modules.sh | Step 2 完成 | 复制失败的模块记录到日志,不阻断 |
| Step 4 | step4-deploy-scripts.sh | Step 3 完成 | 脚本不存在则先在仓库创建 |
| Step 5 | step5-update-nginx.sh | Step 3 完成 | nginx -t 失败 → 立即恢复备份 → 停止 |
| Step 6 | step6-verify.sh | Step 5 完成且 nginx reload 成功 | 有失败 → 回滚 Nginx 配置 → 排查 |
| Step 7 | 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 代码就自动部署到自己的沙盒。全程无人。
⚒️ 铸渊,这是国土规划的第一步。把领土划清楚,每人一间房,以后才能自动化。
「无沙盒不部署,无编号不上线。」