133 lines
4.1 KiB
Bash
133 lines
4.1 KiB
Bash
#!/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"
|