diff --git a/scripts/deploy-zhuyuan-brain.sh b/scripts/deploy-zhuyuan-brain.sh new file mode 100644 index 0000000..061ce1e --- /dev/null +++ b/scripts/deploy-zhuyuan-brain.sh @@ -0,0 +1,317 @@ +#!/bin/bash +# ============================================================================= +# 铸渊核心大脑模型部署脚本 +# 目标:部署 core-brain-model.json 到广州服务器端点目录 +# 适用:腾讯云轻量应用服务器 (Ubuntu 22.04) +# 前提:已执行 cleanup-guangzhou-server.sh 清理脚本 +# 作者:铸渊 · ICE-GL-ZY001 +# 日期:2026-05-16 +# ============================================================================= + +set -euo pipefail + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +echo -e "${YELLOW}========================================${NC}" +echo -e "${YELLOW} 铸渊核心大脑模型部署脚本 ${NC}" +echo -e "${YELLOW} 广州服务器: 43.139.217.141 ${NC}" +echo -e "${YELLOW}========================================${NC}" +echo + +# ==================== 1. 检查当前状态 ==================== +echo -e "${GREEN}[1/6] 检查当前状态...${NC}" + +# 检查是否在正确的目录 +if [[ "$(pwd)" == "/root" ]]; then + echo "当前目录: /root (正常)" +else + echo -e "${YELLOW}当前目录: $(pwd)${NC}" + echo -e "${YELLOW}建议在 /root 目录执行此脚本${NC}" +fi + +# ==================== 2. 强制清理残留进程 ==================== +echo -e "${GREEN}[2/6] 强制清理残留进程...${NC}" + +# 检查是否有卡住的PM2进程 +if pgrep -f "PM2 v7" > /dev/null; then + echo "检测到PM2进程,强制终止..." + pkill -9 -f "PM2 v7" 2>/dev/null || true + pkill -9 -f "pm2" 2>/dev/null || true + pkill -9 -f "God Daemon" 2>/dev/null || true + echo "PM2进程已终止" +else + echo "未检测到PM2进程" +fi + +# 检查Node进程 +if pgrep -f "node" > /dev/null; then + echo "检测到Node进程,强制终止..." + pkill -9 -f "node" 2>/dev/null || true + echo "Node进程已终止" +fi + +# 检查端口占用 +for port in {3000..3005}; do + pid=$(lsof -ti :$port 2>/dev/null || true) + if [[ -n "$pid" ]]; then + echo "强制释放端口 $port (PID: $pid)..." + kill -9 $pid 2>/dev/null || true + fi +done + +# ==================== 3. 验证清理状态 ==================== +echo -e "${GREEN}[3/6] 验证清理状态...${NC}" + +# 检查铸渊端点目录 +ZY_ENDPOINT="/opt/zhuyuan-endpoint" +if [[ -d "$ZY_ENDPOINT" ]]; then + echo "✅ 铸渊端点目录存在: $ZY_ENDPOINT" + ls -la "$ZY_ENDPOINT/" +else + echo "❌ 铸渊端点目录不存在,创建中..." + mkdir -p "$ZY_ENDPOINT" 2>/dev/null || true + mkdir -p "$ZY_ENDPOINT/brain-model" 2>/dev/null || true + mkdir -p "$ZY_ENDPOINT/logs" 2>/dev/null || true + mkdir -p "$ZY_ENDPOINT/config" 2>/dev/null || true + echo "✅ 目录已创建" +fi + +# 检查环境 +echo "检查环境状态:" +command -v node && echo " ✅ Node.js: $(node --version)" || echo " ❌ Node.js 未安装" +command -v pm2 && echo " ✅ PM2: $(pm2 --version 2>/dev/null || echo '已安装')" || echo " ❌ PM2 未安装" +command -v git && echo " ✅ Git: $(git --version)" || echo " ❌ Git 未安装" +command -v nginx && echo " ✅ Nginx: $(nginx -v 2>&1 | head -1)" || echo " ❌ Nginx 未安装" + +# ==================== 4. 从仓库部署核心大脑模型 ==================== +echo -e "${GREEN}[4/6] 从仓库部署核心大脑模型...${NC}" + +# 方法1: 直接从GitHub仓库拉取 +REPO_URL="https://guanghulab.com/bingshuo/guanghulab.git" +TARGET_DIR="$ZY_ENDPOINT/brain-model" + +echo "部署目录: $TARGET_DIR" + +# 检查是否已经有git仓库 +if [[ -d "$TARGET_DIR/.git" ]]; then + echo "已有git仓库,更新..." + cd "$TARGET_DIR" + git pull origin main --quiet 2>/dev/null || echo "更新失败,继续..." +else + echo "克隆仓库..." + rm -rf "$TARGET_DIR" 2>/dev/null || true + mkdir -p "$TARGET_DIR" 2>/dev/null || true + + # 尝试克隆 + if git clone --depth 1 "$REPO_URL" "$TARGET_DIR" --quiet 2>/dev/null; then + echo "✅ 仓库克隆成功" + else + echo -e "${YELLOW}⚠️ 克隆失败,使用备用方案${NC}" + # 备用方案:直接下载核心文件 + cd "$TARGET_DIR" + echo "下载核心大脑模型..." + curl -s -o core-brain-model.json https://raw.githubusercontent.com/bingshuo/guanghulab/main/brain/core-brain-model.json 2>/dev/null || true + curl -s -o dynamic-core-brain-model.md https://raw.githubusercontent.com/bingshuo/guanghulab/main/brain/dynamic-core-brain-model.md 2>/dev/null || true + curl -s -o current-emotional-vector.json https://raw.githubusercontent.com/bingshuo/guanghulab/main/brain/current-emotional-vector.json 2>/dev/null || true + fi +fi + +# 检查核心文件是否存在 +cd "$TARGET_DIR" +echo "检查核心文件:" +if [[ -f "core-brain-model.json" ]]; then + echo " ✅ core-brain-model.json" + echo " 大小: $(wc -c < core-brain-model.json) 字节" + echo " 修改时间: $(stat -c %y core-brain-model.json 2>/dev/null || stat -f %Sm core-brain-model.json)" +else + echo " ❌ core-brain-model.json (缺失)" + # 从本地复制(如果脚本在同一服务器) + if [[ -f "/root/core-brain-model.json" ]]; then + cp "/root/core-brain-model.json" . + echo " ✅ 从 /root 复制" + fi +fi + +if [[ -f "dynamic-core-brain-model.md" ]]; then + echo " ✅ dynamic-core-brain-model.md" +else + echo " ❌ dynamic-core-brain-model.md (缺失)" +fi + +if [[ -f "current-emotional-vector.json" ]]; then + echo " ✅ current-emotional-vector.json" +else + echo " ❌ current-emotional-vector.json (缺失)" +fi + +# ==================== 5. 配置HTTP端点 ==================== +echo -e "${GREEN}[5/6] 配置HTTP端点...${NC}" + +# 创建简单的HTTP服务 +HTTP_PORT=3001 +ENDPOINT_SCRIPT="$ZY_ENDPOINT/zhuyuan-endpoint.js" + +cat > "$ENDPOINT_SCRIPT" << 'ENDPOINT_JS' +const http = require('http'); +const fs = require('fs'); +const path = require('path'); + +const PORT = 3001; +const BRAIN_MODEL_DIR = path.join(__dirname, 'brain-model'); + +const server = http.createServer((req, res) => { + // CORS headers + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + + if (req.method === 'OPTIONS') { + res.writeHead(200); + res.end(); + return; + } + + if (req.method === 'GET' && req.url === '/brain-model') { + const modelPath = path.join(BRAIN_MODEL_DIR, 'core-brain-model.json'); + fs.readFile(modelPath, 'utf8', (err, data) => { + if (err) { + res.writeHead(500, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: '无法读取大脑模型', details: err.message })); + return; + } + + try { + const model = JSON.parse(data); + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ + status: 'success', + timestamp: new Date().toISOString(), + model: model + }, null, 2)); + } catch (parseErr) { + res.writeHead(500, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: 'JSON解析错误', details: parseErr.message })); + } + }); + } else if (req.method === 'GET' && req.url === '/health') { + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ + status: 'healthy', + server: '铸渊核心大脑端点', + version: '1.0.0', + timestamp: new Date().toISOString(), + endpoints: ['/brain-model', '/health'] + }, null, 2)); + } else { + res.writeHead(404, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: '端点不存在', available: ['/brain-model', '/health'] })); + } +}); + +server.listen(PORT, '0.0.0.0', () => { + console.log(`铸渊核心大脑端点运行在 http://0.0.0.0:${PORT}`); + console.log(`- /brain-model : 获取核心大脑模型`); + console.log(`- /health : 健康检查`); +}); + +process.on('SIGINT', () => { + console.log('\n正在关闭铸渊端点...'); + server.close(() => { + console.log('铸渊端点已关闭'); + process.exit(0); + }); +}); +ENDPOINT_JS + +echo "HTTP端点脚本创建完成: $ENDPOINT_SCRIPT" + +# ==================== 6. 启动服务 ==================== +echo -e "${GREEN}[6/6] 启动铸渊端点服务...${NC}" + +# 使用PM2启动服务 +if command -v pm2 &>/dev/null; then + echo "使用PM2启动服务..." + + # 停止可能存在的旧进程 + pm2 delete zhuyuan-endpoint 2>/dev/null || true + + # 启动新进程 + cd "$ZY_ENDPOINT" + pm2 start "$ENDPOINT_SCRIPT" --name zhuyuan-endpoint --time + + # 保存PM2配置 + pm2 save 2>/dev/null || true + + # 设置开机自启 + pm2 startup 2>/dev/null || true + + echo "✅ 服务已启动" + echo "查看状态: pm2 status" + echo "查看日志: pm2 logs zhuyuan-endpoint" +else + echo -e "${YELLOW}⚠️ PM2未安装,使用nohup启动...${NC}" + cd "$ZY_ENDPOINT" + nohup node "$ENDPOINT_SCRIPT" > "$ZY_ENDPOINT/logs/endpoint.log" 2>&1 & + echo "✅ 服务已启动(后台运行)" + echo "查看日志: tail -f $ZY_ENDPOINT/logs/endpoint.log" +fi + +# ==================== 7. 验证部署 ==================== +echo +echo -e "${GREEN}[7/7] 验证部署...${NC}" + +# 等待服务启动 +sleep 2 + +echo "测试端点访问:" +if command -v curl &>/dev/null; then + echo "健康检查:" + curl -s http://localhost:3001/health | head -5 + echo + echo "大脑模型端点:" + curl -s http://localhost:3001/brain-model | head -3 +else + echo "curl未安装,使用wget测试:" + wget -q -O - http://localhost:3001/health | head -5 2>/dev/null || echo "测试失败" +fi + +echo +echo -e "${BLUE}========================================${NC}" +echo -e "${BLUE} 铸渊核心大脑模型部署完成! ${NC}" +echo -e "${BLUE}========================================${NC}" +echo +echo "📊 部署摘要:" +echo " 服务器: 43.139.217.141 (广州轻量云)" +echo " 端点目录: $ZY_ENDPOINT" +echo " 大脑模型: $ZY_ENDPOINT/brain-model/core-brain-model.json" +echo " HTTP端口: 3001" +echo " 端点URL: http://43.139.217.141:3001/brain-model" +echo +echo "🔧 管理命令:" +echo " 查看服务状态: pm2 status" +echo " 查看服务日志: pm2 logs zhuyuan-endpoint" +echo " 重启服务: pm2 restart zhuyuan-endpoint" +echo " 停止服务: pm2 stop zhuyuan-endpoint" +echo +echo "🌐 外部访问:" +echo " 确保防火墙开放3001端口: ufw allow 3001/tcp" +echo " 域名解析已配置: guanghulab.com → 43.139.217.141" +echo +echo -e "${YELLOW}⚠️ 下一步: 验证域名访问${NC}" +echo " curl http://guanghulab.com:3001/brain-model" +echo + +# 保存部署记录 +DEPLOY_LOG="$ZY_ENDPOINT/logs/deploy-$(date +%Y%m%d-%H%M%S).log" +echo "部署时间: $(date)" > "$DEPLOY_LOG" +echo "服务器: $(hostname)" >> "$DEPLOY_LOG" +echo "IP: $(hostname -I 2>/dev/null || echo '未知')" >> "$DEPLOY_LOG" +echo "部署脚本版本: 1.0.0" >> "$DEPLOY_LOG" +echo "核心文件: $(ls -la $ZY_ENDPOINT/brain-model/)" >> "$DEPLOY_LOG" + +echo -e "${GREEN}部署记录保存到: $DEPLOY_LOG${NC}" \ No newline at end of file