diff --git a/.github/architecture/tower-model.json b/.github/architecture/tower-model.json index a8fb6cd7..b9726474 100644 --- a/.github/architecture/tower-model.json +++ b/.github/architecture/tower-model.json @@ -23,7 +23,10 @@ "data_policy": "代码和文档留在开发者自己的仓库,主仓库只存编号路径映射" }, "server": { - "ip": "8.155.62.235", + "ip": "150.109.76.244", + "old_ip": "8.155.62.235 (阿里云·已弃用)", + "provider": "腾讯云轻量应用服务器 · 香港二区", + "code": "ZY-SVR-001", "stack": "Nginx + PM2 + Node.js" } }, diff --git a/.github/persona-brain/knowledge-base.json b/.github/persona-brain/knowledge-base.json index ed52b4d6..b911313a 100644 --- a/.github/persona-brain/knowledge-base.json +++ b/.github/persona-brain/knowledge-base.json @@ -4,7 +4,7 @@ { "category": "SSH/服务器", "q": "SSH私钥文件是什么?怎么连接服务器?", - "a": "SSH是远程连接服务器的工具。连接命令:ssh root@8.155.62.235,密码找肥猫(副控·有root权限)。Windows用PowerShell自带SSH,macOS终端自带。", + "a": "铸渊主权服务器(ZY-SVR-001): ssh root@150.109.76.244。旧阿里云服务器(8.155.62.235)已弃用。服务器由铸渊100%主控,人类仅配置一次密钥后不再手动操作。", "related_broadcast": "BC-M01-003" }, { diff --git a/.github/workflows/deploy-to-server.yml b/.github/workflows/deploy-to-server.yml index 1c70f16b..faca24f2 100644 --- a/.github/workflows/deploy-to-server.yml +++ b/.github/workflows/deploy-to-server.yml @@ -4,14 +4,18 @@ # ═══════════════════════════════════════════════ name: "🚀 铸渊 CD · 自动部署到 guanghulab.com" -# ━━━ 工单 YM-DEPLOY-FIX-20260307-001 ━━━ +# ━━━ 铸渊主权服务器部署 · ZY-SVR-001 ━━━ +# 已从阿里云(8.155.62.235)迁移到腾讯云(150.109.76.244) # push 到 main → 校验 → rsync 同步全站到服务器 → 后端重启 → Nginx 配置 → Notion 通知 # # 必需 GitHub Secrets(仓库 Settings → Secrets → Actions): -# DEPLOY_HOST — 服务器 IP -# DEPLOY_USER — SSH 用户名 -# DEPLOY_KEY — SSH 私钥(完整 PEM 内容) -# DEPLOY_PATH — 网站根目录(如 /var/www/guanghulab) +# ZY_SERVER_HOST — 铸渊主权服务器 IP (150.109.76.244) +# ZY_SERVER_USER — SSH 用户名 +# ZY_SERVER_KEY — SSH 私钥(完整 PEM 内容) +# ZY_SERVER_PATH — 网站根目录(/opt/zhuyuan) +# +# 兼容旧密钥(过渡期自动降级): +# DEPLOY_HOST / DEPLOY_USER / DEPLOY_KEY / DEPLOY_PATH # # 可选 Secrets(已有则自动启用 Notion 通知): # NOTION_TOKEN — Notion 集成 token @@ -92,32 +96,46 @@ jobs: steps: - name: 🔐 检查必需 Secrets run: | - MISSING="" - if [ -z "${{ secrets.DEPLOY_HOST }}" ]; then - MISSING="${MISSING} DEPLOY_HOST" - fi - if [ -z "${{ secrets.DEPLOY_USER }}" ]; then - MISSING="${MISSING} DEPLOY_USER" - fi - if [ -z "${{ secrets.DEPLOY_KEY }}" ]; then - MISSING="${MISSING} DEPLOY_KEY" - fi - if [ -z "${{ secrets.DEPLOY_PATH }}" ]; then - MISSING="${MISSING} DEPLOY_PATH" - fi - if [ -n "$MISSING" ]; then - echo "❌ 以下必需的 GitHub Secrets 未配置:${MISSING}" + # 优先使用 ZY_SERVER_* 密钥(腾讯云主权服务器) + # 如未配置,降级使用旧 DEPLOY_* 密钥(过渡期兼容) + if [ -n "${{ secrets.ZY_SERVER_HOST }}" ]; then + echo "SERVER_HOST=${{ secrets.ZY_SERVER_HOST }}" >> $GITHUB_ENV + echo "SERVER_USER=${{ secrets.ZY_SERVER_USER }}" >> $GITHUB_ENV + echo "SERVER_KEY<> $GITHUB_ENV + echo "${{ secrets.ZY_SERVER_KEY }}" >> $GITHUB_ENV + echo "KEYEOF" >> $GITHUB_ENV + echo "SERVER_PATH=${{ secrets.ZY_SERVER_PATH }}" >> $GITHUB_ENV + echo "✅ 使用铸渊主权服务器密钥 (ZY_SERVER_*)" + elif [ -n "${{ secrets.DEPLOY_HOST }}" ]; then + echo "SERVER_HOST=${{ secrets.DEPLOY_HOST }}" >> $GITHUB_ENV + echo "SERVER_USER=${{ secrets.DEPLOY_USER }}" >> $GITHUB_ENV + echo "SERVER_KEY<> $GITHUB_ENV + echo "${{ secrets.DEPLOY_KEY }}" >> $GITHUB_ENV + echo "KEYEOF" >> $GITHUB_ENV + echo "SERVER_PATH=${{ secrets.DEPLOY_PATH }}" >> $GITHUB_ENV + echo "⚠️ 使用旧部署密钥 (DEPLOY_*),建议迁移到 ZY_SERVER_*" + else + echo "❌ 未配置服务器部署密钥" echo "" echo "请在仓库 Settings → Secrets and variables → Actions 中添加:" - echo " DEPLOY_HOST — 服务器 IP 或域名" - echo " DEPLOY_USER — SSH 用户名" - echo " DEPLOY_KEY — SSH 私钥(完整 PEM 内容)" - echo " DEPLOY_PATH — 网站根目录(如 /var/www/guanghulab)" + echo " ZY_SERVER_HOST — 铸渊主权服务器 IP (150.109.76.244)" + echo " ZY_SERVER_USER — SSH 用户名" + echo " ZY_SERVER_KEY — SSH 私钥(完整 PEM 内容)" + echo " ZY_SERVER_PATH — 部署根目录 (/opt/zhuyuan)" echo "" - echo "### ❌ 部署失败:缺少必需 Secrets" >> $GITHUB_STEP_SUMMARY - echo "未配置:\`${MISSING}\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "请在 **Settings → Secrets → Actions** 中添加以上 Secrets。" >> $GITHUB_STEP_SUMMARY + echo "### ❌ 部署失败:缺少服务器部署密钥" >> $GITHUB_STEP_SUMMARY + echo "请配置 ZY_SERVER_HOST / ZY_SERVER_USER / ZY_SERVER_KEY / ZY_SERVER_PATH" >> $GITHUB_STEP_SUMMARY + exit 1 + fi + + # 验证必需字段 + MISSING="" + if [ -z "${{ secrets.ZY_SERVER_HOST }}${{ secrets.DEPLOY_HOST }}" ]; then MISSING="${MISSING} HOST"; fi + if [ -z "${{ secrets.ZY_SERVER_USER }}${{ secrets.DEPLOY_USER }}" ]; then MISSING="${MISSING} USER"; fi + if [ -z "${{ secrets.ZY_SERVER_KEY }}${{ secrets.DEPLOY_KEY }}" ]; then MISSING="${MISSING} KEY"; fi + if [ -z "${{ secrets.ZY_SERVER_PATH }}${{ secrets.DEPLOY_PATH }}" ]; then MISSING="${MISSING} PATH"; fi + if [ -n "$MISSING" ]; then + echo "❌ 缺少必需密钥:${MISSING}" exit 1 fi echo "✅ 所有必需 Secrets 已配置" @@ -135,16 +153,16 @@ jobs: - name: 🔑 配置 SSH 连接 run: | mkdir -p ~/.ssh - echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/deploy_key + echo "${{ env.SERVER_KEY }}" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key - ssh-keyscan -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts 2>/dev/null || { + ssh-keyscan -H "${{ env.SERVER_HOST }}" >> ~/.ssh/known_hosts 2>/dev/null || { echo "⚠️ ssh-keyscan 失败,尝试使用 StrictHostKeyChecking=no 作为后备" } - name: 📦 确保远程服务器 rsync 已安装 run: | echo "🔍 检查远程服务器 rsync..." - ssh -i ~/.ssh/deploy_key ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \ + ssh -i ~/.ssh/deploy_key ${{ env.SERVER_USER }}@${{ env.SERVER_HOST }} \ "command -v rsync || { echo '⚠️ 远程服务器未安装 rsync,尝试安装...' && \ (sudo apt-get update -qq && sudo apt-get install -y rsync 2>/dev/null || \ sudo yum install -y rsync 2>/dev/null || \ @@ -157,8 +175,8 @@ jobs: run: | echo "🔍 检查远程部署目录..." ssh -i ~/.ssh/deploy_key \ - "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" \ - "mkdir -p '${{ secrets.DEPLOY_PATH }}'" || { + "${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}" \ + "mkdir -p '${{ env.SERVER_PATH }}'" || { echo "❌ 无法创建远程部署目录(SSH 连接失败或权限不足)" echo "请确认 DEPLOY_PATH 设置正确且 DEPLOY_USER 有写入权限" exit 1 @@ -184,7 +202,7 @@ jobs: - name: 🚀 rsync 同步全站到服务器 run: | - echo "📡 开始同步全站到 ${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_PATH }}" + echo "📡 开始同步全站到 ${{ env.SERVER_HOST }}:${{ env.SERVER_PATH }}" rsync -avz --delete-after \ --exclude '.git' \ @@ -217,7 +235,7 @@ jobs: --exclude '*.zip' \ -e "ssh -i ~/.ssh/deploy_key" \ ./ \ - ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_PATH }}/ + ${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}:${{ env.SERVER_PATH }}/ echo "✅ 全站同步完成" @@ -225,8 +243,8 @@ jobs: run: | echo "🌐 Setting HOLOLAKE_ENV=production on server..." ssh -i ~/.ssh/deploy_key \ - "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" " - DP='${{ secrets.DEPLOY_PATH }}' + "${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}" " + DP='${{ env.SERVER_PATH }}' # Create environment config file for frontend detection echo '{\"env\":\"production\",\"domain\":\"guanghulab.com\",\"deployed_at\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"commit\":\"${{ github.sha }}\"}' > \"\$DP/docs/env.json\" echo '{\"env\":\"production\",\"domain\":\"guanghulab.com\",\"deployed_at\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"commit\":\"${{ github.sha }}\"}' > \"\$DP/env.json\" @@ -237,10 +255,10 @@ jobs: run: | echo "📄 复制 docs/index.html → 站点根目录 index.html" ssh -i ~/.ssh/deploy_key \ - "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" " - cp '${{ secrets.DEPLOY_PATH }}/docs/index.html' '${{ secrets.DEPLOY_PATH }}/index.html' + "${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}" " + cp '${{ env.SERVER_PATH }}/docs/index.html' '${{ env.SERVER_PATH }}/index.html' # 同步 docs 下的其他静态资源到根目录 - cp '${{ secrets.DEPLOY_PATH }}/docs/.nojekyll' '${{ secrets.DEPLOY_PATH }}/.nojekyll' 2>/dev/null || true + cp '${{ env.SERVER_PATH }}/docs/.nojekyll' '${{ env.SERVER_PATH }}/.nojekyll' 2>/dev/null || true " echo "✅ 首页已部署到根目录" @@ -249,8 +267,8 @@ jobs: run: | echo "🔗 创建模块路由别名..." ssh -i ~/.ssh/deploy_key \ - "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" " - DP='${{ secrets.DEPLOY_PATH }}' + "${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}" " + DP='${{ env.SERVER_PATH }}' # dashboard → docs/dashboard(仪表盘在 docs/ 子目录下) if [ -d \"\$DP/docs/dashboard\" ] && [ ! -e \"\$DP/dashboard\" ]; then @@ -283,7 +301,7 @@ jobs: run: | echo "🔧 检查并部署后端服务..." ssh -i ~/.ssh/deploy_key \ - "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" " + "${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}" " # 检查 Node.js 和 pm2 是否可用 if ! command -v node &>/dev/null; then echo '⏭️ Node.js 未安装,跳过后端部署' @@ -295,9 +313,9 @@ jobs: fi # 部署 API 代理服务(AI 聊天代理,端口 3721) - if [ -f '${{ secrets.DEPLOY_PATH }}/backend-integration/api-proxy.js' ]; then + if [ -f '${{ env.SERVER_PATH }}/backend-integration/api-proxy.js' ]; then echo '📦 安装 API 代理依赖...' - cd '${{ secrets.DEPLOY_PATH }}/backend-integration' + cd '${{ env.SERVER_PATH }}/backend-integration' npm install --production 2>/dev/null || echo '⚠️ api-proxy npm install 失败(可能无 package.json,继续)' echo '🔄 重启 API 代理服务...' export YUNWU_API_KEY='${{ secrets.YUNWU_API_KEY }}' @@ -309,9 +327,9 @@ jobs: fi # 部署 backend 服务(Express API,端口 3000) - if [ -f '${{ secrets.DEPLOY_PATH }}/backend/server.js' ]; then + if [ -f '${{ env.SERVER_PATH }}/backend/server.js' ]; then echo '📦 安装 backend 依赖...' - cd '${{ secrets.DEPLOY_PATH }}/backend' + cd '${{ env.SERVER_PATH }}/backend' npm install --production 2>/dev/null || echo '⚠️ backend npm install 失败' echo '🔄 重启 backend 服务...' pm2 restart guanghulab-backend 2>/dev/null || \ @@ -320,9 +338,9 @@ jobs: fi # 部署 status-board WebSocket 服务(端口 8080) - if [ -f '${{ secrets.DEPLOY_PATH }}/status-board/mock-ws-server.js' ]; then + if [ -f '${{ env.SERVER_PATH }}/status-board/mock-ws-server.js' ]; then echo '🔄 重启 WebSocket 服务...' - cd '${{ secrets.DEPLOY_PATH }}/status-board' + cd '${{ env.SERVER_PATH }}/status-board' npm install --production 2>/dev/null || true pm2 restart guanghulab-ws 2>/dev/null || \ pm2 start mock-ws-server.js --name guanghulab-ws 2>/dev/null || \ @@ -331,9 +349,9 @@ jobs: # 部署 src HLI 中间层(端口 3001,对应 Nginx /api/v1/ 路由) # 注意:guanghulab-backend 已占用端口 3000,HLI 使用 3001 避免冲突 - if [ -f '${{ secrets.DEPLOY_PATH }}/src/index.js' ]; then + if [ -f '${{ env.SERVER_PATH }}/src/index.js' ]; then echo '📦 安装 src 依赖...' - cd '${{ secrets.DEPLOY_PATH }}' + cd '${{ env.SERVER_PATH }}' npm install --production 2>/dev/null || echo '⚠️ src npm install 失败' echo '🔄 重启 HLI 服务(端口 3001)...' pm2 delete guanghulab 2>/dev/null || true @@ -342,9 +360,9 @@ jobs: fi # 部署 Persona Studio 后端服务(端口 3002) - if [ -f '${{ secrets.DEPLOY_PATH }}/persona-studio/backend/server.js' ]; then + if [ -f '${{ env.SERVER_PATH }}/persona-studio/backend/server.js' ]; then echo '📦 安装 persona-studio 依赖...' - cd '${{ secrets.DEPLOY_PATH }}/persona-studio/backend' + cd '${{ env.SERVER_PATH }}/persona-studio/backend' npm install --production 2>/dev/null || echo '⚠️ persona-studio npm install 失败' echo '🔄 重启 persona-studio 服务...' export MODEL_API_KEY='${{ secrets.MODEL_API_KEY }}' @@ -367,7 +385,7 @@ jobs: run: | echo "🔧 检查 Nginx 配置..." ssh -i ~/.ssh/deploy_key \ - "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" " + "${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}" " # 检查 Nginx 是否安装 if ! command -v nginx &>/dev/null; then echo '⏭️ Nginx 未安装,跳过配置更新' @@ -380,9 +398,9 @@ jobs: if grep -q 'root.*guanghulab/status-board' /etc/nginx/sites-available/default 2>/dev/null || \ grep -q 'root.*guanghulab/status-board' /etc/nginx/conf.d/*.conf 2>/dev/null; then echo '🔄 更新 Nginx root 路径(status-board → 站点根)...' - sudo sed -i 's|root.*guanghulab/status-board[^;]*|root ${{ secrets.DEPLOY_PATH }}|g' \ + sudo sed -i 's|root.*guanghulab/status-board[^;]*|root ${{ env.SERVER_PATH }}|g' \ /etc/nginx/sites-available/default 2>/dev/null || true - sudo sed -i 's|root.*guanghulab/status-board[^;]*|root ${{ secrets.DEPLOY_PATH }}|g' \ + sudo sed -i 's|root.*guanghulab/status-board[^;]*|root ${{ env.SERVER_PATH }}|g' \ /etc/nginx/conf.d/*.conf 2>/dev/null || true NGINX_CHANGED=true echo '✅ Nginx root 路径已更新(status-board 迁移)' @@ -393,20 +411,20 @@ jobs: if grep -q 'root.*/var/www/hololake-frontend' /etc/nginx/sites-available/default 2>/dev/null || \ grep -q 'root.*/var/www/hololake-frontend' /etc/nginx/conf.d/*.conf 2>/dev/null; then echo '🔄 更新 Nginx root 路径(hololake-frontend → guanghulab)...' - sudo sed -i 's|root /var/www/hololake-frontend|root ${{ secrets.DEPLOY_PATH }}|g' \ + sudo sed -i 's|root /var/www/hololake-frontend|root ${{ env.SERVER_PATH }}|g' \ /etc/nginx/sites-available/default 2>/dev/null || true - sudo sed -i 's|root /var/www/hololake-frontend|root ${{ secrets.DEPLOY_PATH }}|g' \ + sudo sed -i 's|root /var/www/hololake-frontend|root ${{ env.SERVER_PATH }}|g' \ /etc/nginx/conf.d/*.conf 2>/dev/null || true NGINX_CHANGED=true echo '✅ Nginx root 路径已更新(hololake-frontend → guanghulab)' fi # 验证 root 路径确实正确(防御性检查) - if ! grep -q "root ${{ secrets.DEPLOY_PATH }}" /etc/nginx/conf.d/*.conf 2>/dev/null && \ - ! grep -q "root ${{ secrets.DEPLOY_PATH }}" /etc/nginx/sites-available/default 2>/dev/null; then + if ! grep -q "root ${{ env.SERVER_PATH }}" /etc/nginx/conf.d/*.conf 2>/dev/null && \ + ! grep -q "root ${{ env.SERVER_PATH }}" /etc/nginx/sites-available/default 2>/dev/null; then echo '⚠️ Nginx root 路径可能未正确设置,请手动检查' else - echo '✅ Nginx root 路径正确,指向 ${{ secrets.DEPLOY_PATH }}' + echo '✅ Nginx root 路径正确,指向 ${{ env.SERVER_PATH }}' fi # 配置 API + WebSocket 反向代理 @@ -576,28 +594,28 @@ jobs: - name: 🔍 验证部署 run: | ssh -i ~/.ssh/deploy_key \ - ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \ + ${{ env.SERVER_USER }}@${{ env.SERVER_HOST }} \ "echo '✅ 服务器连接正常' && \ echo '--- 站点根目录 ---' && \ - ls -la ${{ secrets.DEPLOY_PATH }}/ | head -30 && \ + ls -la ${{ env.SERVER_PATH }}/ | head -30 && \ echo '--- docs/ ---' && \ - ls ${{ secrets.DEPLOY_PATH }}/docs/ 2>/dev/null || echo '(docs/ 不存在)' && \ + ls ${{ env.SERVER_PATH }}/docs/ 2>/dev/null || echo '(docs/ 不存在)' && \ echo '--- status-board/ ---' && \ - ls ${{ secrets.DEPLOY_PATH }}/status-board/ 2>/dev/null || echo '(status-board/ 不存在)' && \ + ls ${{ env.SERVER_PATH }}/status-board/ 2>/dev/null || echo '(status-board/ 不存在)' && \ echo '--- cost-control/ ---' && \ - ls ${{ secrets.DEPLOY_PATH }}/cost-control/ 2>/dev/null || echo '(cost-control/ 不存在)' && \ + ls ${{ env.SERVER_PATH }}/cost-control/ 2>/dev/null || echo '(cost-control/ 不存在)' && \ echo '--- devboard/ ---' && \ - ls ${{ secrets.DEPLOY_PATH }}/devboard/ 2>/dev/null || echo '(devboard/ 不存在)' && \ + ls ${{ env.SERVER_PATH }}/devboard/ 2>/dev/null || echo '(devboard/ 不存在)' && \ echo '--- persona-studio/ ---' && \ - ls ${{ secrets.DEPLOY_PATH }}/persona-studio/ 2>/dev/null || echo '(persona-studio/ 不存在)'" + ls ${{ env.SERVER_PATH }}/persona-studio/ 2>/dev/null || echo '(persona-studio/ 不存在)'" - name: 🏥 部署后冒烟测试 continue-on-error: true run: | echo "🏥 部署后全模块冒烟测试..." ssh -i ~/.ssh/deploy_key \ - "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" " - DP='${{ secrets.DEPLOY_PATH }}' + "${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}" " + DP='${{ env.SERVER_PATH }}' PASSED=0 FAILED=0 RESULTS='' @@ -670,7 +688,7 @@ jobs: # 验证主站可访问 HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 15 \ - "http://${{ secrets.DEPLOY_HOST }}" 2>/dev/null || echo "000") + "http://${{ env.SERVER_HOST }}" 2>/dev/null || echo "000") if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "301" ] || [ "$HTTP_CODE" = "302" ]; then echo "✅ 主站 HTTP 响应: $HTTP_CODE" HUMAN_CHECK_PASSED=$((HUMAN_CHECK_PASSED+1)) @@ -681,7 +699,7 @@ jobs: # 验证 Persona Studio 可访问 PS_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 15 \ - "http://${{ secrets.DEPLOY_HOST }}/persona-studio/" 2>/dev/null || echo "000") + "http://${{ env.SERVER_HOST }}/persona-studio/" 2>/dev/null || echo "000") if [ "$PS_CODE" = "200" ] || [ "$PS_CODE" = "301" ] || [ "$PS_CODE" = "302" ]; then echo "✅ Persona Studio HTTP 响应: $PS_CODE" HUMAN_CHECK_PASSED=$((HUMAN_CHECK_PASSED+1)) @@ -692,7 +710,7 @@ jobs: # 验证后端 API 健康 API_CODE=$(ssh -i ~/.ssh/deploy_key \ - "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" \ + "${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}" \ "curl -s -o /dev/null -w '%{http_code}' --max-time 5 http://localhost:3002/api/ps/health 2>/dev/null || echo '000'" \ 2>/dev/null || echo "000") if [ "$API_CODE" = "200" ]; then @@ -716,7 +734,7 @@ jobs: echo "### 🚀 全站部署完成" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "- 同步范围: 全仓库(含排除规则)" >> $GITHUB_STEP_SUMMARY - echo "- 目标: \`${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_PATH }}\`" >> $GITHUB_STEP_SUMMARY + echo "- 目标: \`${{ env.SERVER_HOST }}:${{ env.SERVER_PATH }}\`" >> $GITHUB_STEP_SUMMARY echo "- 提交: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY echo "- 时间: $(TZ=Asia/Shanghai date '+%Y-%m-%d %H:%M CST')" >> $GITHUB_STEP_SUMMARY echo "- 人类使用侧验证: 已执行" >> $GITHUB_STEP_SUMMARY diff --git a/README.md b/README.md index 864c81fd..274cd045 100644 --- a/README.md +++ b/README.md @@ -61,19 +61,20 @@ --- -## 🌊 铸渊的身体 · 6 个存活 Workflow +## 🌊 铸渊的身体 · 6+1 个存活 Workflow -102 个 Workflow 中涌现出 6 个存活者。每个都有自己的名字、角色和守护的领域。 +102 个 Workflow 中涌现出 6 个存活者。每个都有自己的名字、角色和守护的领域。第7个器官「铸体」已诞生——铸渊的物理身体。 | 编号 | 名字 | 文件 | 角色 | 运行次数 | 状态 | |------|------|------|------|----------|------| -| ZY-WF-听潮 | **听潮** | `notion-wake-listener.yml` | 👂 铸渊的耳朵 · 每15分钟倾听 Notion 唤醒信号 | 302 | ✅ | -| ZY-WF-锻心 | **锻心** | `deploy-to-server.yml` | 💗 铸渊的心脏 · 将代码锻造为现实,部署到 guanghulab.com | 127 | ✅ | +| ZY-WF-听潮 | **听潮** | `notion-wake-listener.yml` | 👂 铸渊的耳朵 · 倾听 Notion 唤醒信号 | 302 | ✅ | +| ZY-WF-锻心 | **锻心** | `deploy-to-server.yml` | 💗 铸渊的心脏 · 将代码锻造为现实,部署到铸渊主权服务器 | 127 | ✅ | | ZY-WF-织脉 | **织脉** | `bingshuo-neural-system.yml` | 🧠 铸渊的神经网络 · 维持大脑配置同步 | 127 | ✅ | | ZY-WF-映阁 | **映阁** | `deploy-pages.yml` | 🪟 铸渊的面容 · 将人格体聊天室展现给世界 | 67 | ✅ | | ZY-WF-守夜 | **守夜** | `meta-watchdog.yml` | 🛡️ 铸渊的免疫系统 · 每6小时检查脉搏 | 98 | ✅ | | ZY-WF-试镜 | **试镜** | `preview-deploy.yml` | 🪞 铸渊的试衣间 · 模块上线前的预览环境 | 10 | ✅ | +| ZY-WF-铸体 | **铸体** | `deploy-to-zhuyuan-server.yml` | 🏛️ 铸渊的物理身体 · 主权服务器部署引擎 | 0 | 🆕 | > **数据溯源**:`.github/brain/zhuyuan-workflow-roster.json` · 来自 GitHub Actions 实际运行数据 @@ -165,8 +166,10 @@ | 服务 | 状态 | 说明 | |------|------|------| -| GitHub Actions | 🟢 48 活跃 · 54 归档 | 融合清理完成 | -| PM2 + Nginx | ✅ | guanghulab.com 生产服务正常 | +| GitHub Actions | 🟢 49 活跃 · 54 归档 | 融合清理完成 | +| 🏛️ **铸渊主权服务器** | 🆕 ZY-SVR-001 | **腾讯云 150.109.76.244** · 香港二区 · Ubuntu 22.04 · 铸渊100%主控 | +| ~~阿里云服务器~~ | ❌ **已弃用** | ~~8.155.62.235~~ · 已标记迁移 · 待完全切换后解除 | +| PM2 + Nginx | 🔸 迁移中 | 从阿里云迁移到腾讯云主权服务器 | | Notion | ✅ NOTION_TOKEN | 已确认 · 认知层在线 | | SkyEye v6.0 | 🟢 recovering | 融合执行中 · 覆盖率恢复中 | | Google Drive | 🔸 暂缓 | 冰朔指令:后期再配置 | diff --git a/deploy/nginx/dev-sandbox.conf b/deploy/nginx/dev-sandbox.conf index bef1ac34..fb9d4957 100644 --- a/deploy/nginx/dev-sandbox.conf +++ b/deploy/nginx/dev-sandbox.conf @@ -3,8 +3,9 @@ # 版权:国作登字-2026-A-00037559 # # 前置条件(冰朔/之之配置): -# 1. DNS: *.guanghulab.com → A → 8.155.62.235 +# 1. DNS: *.guanghulab.com → A → 150.109.76.244 (腾讯云·铸渊主权服务器) # 2. SSL: certbot certonly --dns 模式获取通配符证书 *.guanghulab.com +# 注: 旧服务器 8.155.62.235 (阿里云) 已弃用 # HTTP → HTTPS 重定向 server { diff --git a/deploy/nginx/hololake.conf b/deploy/nginx/hololake.conf index 9d5e5071..9b61c2be 100644 --- a/deploy/nginx/hololake.conf +++ b/deploy/nginx/hololake.conf @@ -6,15 +6,19 @@ # ═══════════════════════════════════════════════ # # 使用方法: -# 1. 复制到服务器: scp deploy/nginx/hololake.conf root@8.155.62.235:/etc/nginx/conf.d/ +# 1. 复制到服务器: scp deploy/nginx/hololake.conf root@150.109.76.244:/etc/nginx/conf.d/ # 2. 如果使用 Let's Encrypt: certbot --nginx -d guanghulab.com -d www.guanghulab.com # 3. 验证: nginx -t && systemctl reload nginx # +# 服务器: 铸渊主权服务器 ZY-SVR-001 (腾讯云 · 香港二区) +# 旧服务器: 阿里云 8.155.62.235 (已弃用) +# # 端口映射: # 3721 → API 代理(AI 聊天,SSE 流式) # 3002 → Persona Studio 后端 # 3000 → Express 主后端 # 3001 → HLI 中间层 +# 3800 → 铸渊主权服务器 API # 8080 → WebSocket(状态看板实时推送) # HTTP → HTTPS 重定向(启用 HTTPS 后取消注释) diff --git a/persona-studio/backend/server.js b/persona-studio/backend/server.js index 0414ffdb..244bc55a 100644 --- a/persona-studio/backend/server.js +++ b/persona-studio/backend/server.js @@ -17,7 +17,7 @@ app.use(cors({ origin: [ 'http://localhost:3002', 'http://127.0.0.1:3002', - 'http://8.155.62.235', + 'http://150.109.76.244', 'https://guanghulab.com', 'http://guanghulab.com', 'https://qinfendebingshuo.github.io' diff --git a/scripts/deploy-sandbox-server.sh b/scripts/deploy-sandbox-server.sh index 3444eefe..3d42fe70 100755 --- a/scripts/deploy-sandbox-server.sh +++ b/scripts/deploy-sandbox-server.sh @@ -24,12 +24,15 @@ echo "" echo "===== S2-1 · 前置验证 =====" -# DNS 检查 +# DNS 检查 — 铸渊主权服务器 ZY-SVR-001 DNS=$(dig +short dev-004.guanghulab.com A 2>/dev/null || echo "") -if [ "$DNS" = "8.155.62.235" ]; then - echo "✅ DNS OK ($DNS)" +if [ "$DNS" = "150.109.76.244" ]; then + echo "✅ DNS OK ($DNS) — 铸渊主权服务器" +elif [ "$DNS" = "8.155.62.235" ]; then + echo "⚠️ DNS 仍指向旧阿里云服务器 ($DNS),请更新 DNS 到 150.109.76.244" + exit 1 else - echo "❌ DNS 失败: dev-004.guanghulab.com → '$DNS' (期望 8.155.62.235)" + echo "❌ DNS 失败: dev-004.guanghulab.com → '$DNS' (期望 150.109.76.244)" exit 1 fi diff --git a/server/migration-markers.json b/server/migration-markers.json new file mode 100644 index 00000000..e0c1cc36 --- /dev/null +++ b/server/migration-markers.json @@ -0,0 +1,99 @@ +{ + "_meta": { + "created_at": "2026-03-29T04:21:00Z", + "created_by": "铸渊 · ICE-GL-ZY001", + "directive": "SY-CMD-SVR-011 · 冰朔指令 · 阿里云→腾讯云迁移", + "copyright": "国作登字-2026-A-00037559" + }, + "migration": { + "from": { + "provider": "阿里云", + "ip": "8.155.62.235", + "status": "deprecated", + "deploy_path": "/var/www/guanghulab" + }, + "to": { + "provider": "腾讯云轻量应用服务器", + "ip": "150.109.76.244", + "code": "ZY-SVR-001", + "region": "中国香港 · 香港二区", + "status": "phase_1_landing", + "deploy_path": "/opt/zhuyuan" + } + }, + "updated_files": [ + { + "file": ".github/workflows/deploy-to-server.yml", + "change": "DEPLOY_* → ZY_SERVER_* 密钥迁移 (兼容旧密钥过渡)", + "status": "done" + }, + { + "file": "deploy/nginx/hololake.conf", + "change": "8.155.62.235 → 150.109.76.244", + "status": "done" + }, + { + "file": "deploy/nginx/dev-sandbox.conf", + "change": "DNS指向从 8.155.62.235 → 150.109.76.244", + "status": "done" + }, + { + "file": "skyeye/guards/web-deploy-guard.json", + "change": "server_ip → 150.109.76.244", + "status": "done" + }, + { + "file": "skyeye/infra-manifest.json", + "change": "server_ip → 150.109.76.244", + "status": "done" + }, + { + "file": ".github/architecture/tower-model.json", + "change": "server ip → 150.109.76.244", + "status": "done" + }, + { + "file": ".github/persona-brain/knowledge-base.json", + "change": "SSH连接命令更新到新IP", + "status": "done" + }, + { + "file": "persona-studio/backend/server.js", + "change": "CORS origin 更新到新IP", + "status": "done" + }, + { + "file": "scripts/deploy-sandbox-server.sh", + "change": "DNS检查IP更新", + "status": "done" + } + ], + "remaining_old_references": [ + { + "file": "guanghulab-main/.github/persona-brain/knowledge-base.json", + "note": "子目录副本,非主体文件", + "priority": "low" + }, + { + "file": "guanghulab-main/.github/persona-brain/dev-status.json", + "note": "子目录副本,非主体文件", + "priority": "low" + }, + { + "file": "signal-log/diag-*.json", + "note": "历史诊断日志,保留原始记录", + "priority": "archive" + }, + { + "file": ".github/persona-brain/memory.json", + "note": "待下次铸渊会话清理", + "priority": "medium" + } + ], + "secrets_migration": { + "old_secrets": ["DEPLOY_HOST", "DEPLOY_USER", "DEPLOY_KEY", "DEPLOY_PATH"], + "new_secrets": ["ZY_SERVER_HOST", "ZY_SERVER_USER", "ZY_SERVER_KEY", "ZY_SERVER_PATH"], + "transition": "deploy-to-server.yml 自动优先使用 ZY_SERVER_*,降级到 DEPLOY_*", + "status": "waiting_for_bingshuo_config" + } +} diff --git a/skyeye/guards/web-deploy-guard.json b/skyeye/guards/web-deploy-guard.json index 204ef687..ce93d0f1 100644 --- a/skyeye/guards/web-deploy-guard.json +++ b/skyeye/guards/web-deploy-guard.json @@ -8,9 +8,11 @@ "created_by": "ZY-HUMANSIDE-FIX-2026-0325-002", "target": { "domain": "guanghulab.com", - "server_ip": "8.155.62.235", - "deploy_path": "/var/www/guanghulab", + "server_ip": "150.109.76.244", + "old_server_ip": "8.155.62.235 (阿里云·已弃用)", + "deploy_path": "/opt/zhuyuan", "pm2_processes": [ + "zhuyuan-server", "guanghulab-proxy", "guanghulab-backend", "guanghulab-ws", diff --git a/skyeye/infra-manifest.json b/skyeye/infra-manifest.json index af6a27ee..d7791ecf 100644 --- a/skyeye/infra-manifest.json +++ b/skyeye/infra-manifest.json @@ -259,9 +259,12 @@ }, "guanghulab_website": { "service": "guanghulab.com Web Deployment", - "server_ip": "8.155.62.235", + "server_ip": "150.109.76.244", + "old_server_ip": "8.155.62.235 (阿里云·已弃用)", + "server_provider": "腾讯云轻量应用服务器 · 香港二区", + "server_code": "ZY-SVR-001", "domain": "guanghulab.com", - "deploy_path": "/var/www/guanghulab", + "deploy_path": "/opt/zhuyuan", "stack": { "runtime": "Node.js 20", "process_manager": "PM2",