#!/bin/bash # Hermes Server 部署脚本 # 在 Hermes 服务器上执行:bash deploy/deploy.sh set -e APP_DIR="/opt/hermes-server" APP_USER="hermes" NODE_VERSION="20" echo "===== Hermes Server 部署脚本 =====" # 1. 检查 Node.js if ! command -v node &> /dev/null; then echo "安装 Node.js $NODE_VERSION..." curl -fsSL https://deb.nodesource.com/setup_$NODE_VERSION.x | sudo -E bash - sudo apt-get install -y nodejs fi echo "Node.js 版本: $(node -v)" # 2. 创建用户和目录 if ! id "$APP_USER" &> /dev/null; then sudo useradd -r -m -d /home/$APP_USER -s /bin/bash $APP_USER echo "创建用户: $APP_USER" fi sudo mkdir -p $APP_DIR sudo chown -R $APP_USER:$APP_USER $APP_DIR # 3. 复制代码(假设当前目录是项目根目录) echo "复制代码到 $APP_DIR..." sudo -u $APP_USER cp -r package.json package-lock.json server.js src $APP_DIR/ sudo -u $APP_USER cp -r deploy $APP_DIR/ 2>/dev/null || true # .env.example 位于项目根目录,而非 deploy/ 子目录 sudo -u $APP_USER cp .env.example $APP_DIR/.env.example 2>/dev/null || true # 4. 安装依赖 echo "安装依赖..." cd $APP_DIR # 优先使用 npm ci(依赖 package-lock.json,可重现构建),失败则回退到 npm install if [ -f package-lock.json ]; then sudo -u $APP_USER npm ci --production || sudo -u $APP_USER npm install --production else sudo -u $APP_USER npm install --production fi # 5. 创建数据目录 sudo -u $APP_USER mkdir -p $APP_DIR/data/profiles $APP_DIR/data/qrcodes # 6. 配置环境变量 if [ ! -f $APP_DIR/.env ]; then echo "创建 .env 配置文件..." # .env.example 已在第 3 步拷贝到 $APP_DIR 根目录 if [ -f $APP_DIR/.env.example ]; then sudo -u $APP_USER cp $APP_DIR/.env.example $APP_DIR/.env else # 如果没有 .env.example,创建一个基本的 sudo -u $APP_USER bash -c "cat > $APP_DIR/.env << 'ENVEOF' PORT=3002 HERMES_BASE_URL=http://localhost:3002 ETERNALAI_BASE_URL=http://localhost:3001 SYNC_SECRET= HERMES_ADMIN_TOKEN=$(openssl rand -hex 32) NODE_ENV=production ENVEOF" fi echo "⚠️ 请编辑 $APP_DIR/.env 配置 SYNC_SECRET、HERMES_BASE_URL 和 ETERNALAI_BASE_URL" fi # 7. 配置 PM2 echo "配置 PM2..." if ! command -v pm2 &> /dev/null; then sudo npm install -g pm2 fi sudo -u $APP_USER bash -c "cat > $APP_DIR/ecosystem.config.js << 'PM2EOF' module.exports = { apps: [{ name: 'hermes-server', script: 'server.js', cwd: '$APP_DIR', instances: 1, autorestart: true, max_memory_restart: '256M', env: { NODE_ENV: 'production', }, }], }; PM2EOF" pm2 delete hermes-server 2>/dev/null || true pm2 start $APP_DIR/ecosystem.config.js pm2 save # 8. 配置 Nginx(可选) NGINX_CONF="/etc/nginx/sites-available/hermes-server" if command -v nginx &> /dev/null && [ ! -f "$NGINX_CONF" ]; then echo "配置 Nginx..." sudo bash -c "cat > $NGINX_CONF << 'NGINXEOF' server { listen 80; server_name _; # 替换为你的域名 location / { proxy_pass http://127.0.0.1:3002; 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_set_header X-Forwarded-For \\\$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \\\$scheme; proxy_cache_bypass \\\$http_upgrade; } } NGINXEOF" sudo ln -sf $NGINX_CONF /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx echo "Nginx 已配置" fi echo "" echo "===== 部署完成 =====" echo "" echo "后续步骤:" echo "1. 编辑配置: sudo -u $APP_USER nano $APP_DIR/.env" echo " - SYNC_SECRET: 从 EternalAI 数据库获取(SELECT value FROM \"SystemConfig\" WHERE key='SYNC_SECRET')" echo " - HERMES_BASE_URL: 设置为外部可访问的地址(如 https://hermes.yourdomain.com)" echo " - ETERNALAI_BASE_URL: EternalAI 服务器地址(如 https://eternalai.yourdomain.com)" echo "2. 重启服务: pm2 restart hermes-server" echo "3. 在 EternalAI 管理后台配置 HERMES_WEBHOOK_URL 为: \${HERMES_BASE_URL}/api/sync" echo "4. 健康检查: curl http://localhost:3002/api/health"