- 创建 /api/enhance 路由,实现图片变清晰API集成 - 在图片标注组件中添加变清晰按钮(Sparkles图标) - 在相册页面添加变清晰按钮 - 系统设置:将抠图设置改名为本地AI设置,添加变清晰API配置 - 支持同步和异步两种模式 - 自动上传到S3存储桶并保存到数据库 - 在相册和出图记录中显示处理后的图片
491 lines
15 KiB
Bash
Executable File
491 lines
15 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# 服务器迁移脚本 - 从Git仓库拉取源码和备份数据库
|
||
# 新服务器配置:45.192.99.48,端口3125,域名ai.yydd.ai,HTTPS
|
||
|
||
set -e # 遇到错误立即退出
|
||
|
||
# 新服务器配置
|
||
NEW_SERVER="45.192.99.48"
|
||
NEW_PORT="22"
|
||
NEW_USER="root"
|
||
NEW_PASS="O1zqP731oZ"
|
||
DOMAIN="ai.yydd.ai"
|
||
APP_PORT="3125"
|
||
|
||
# Git仓库配置
|
||
GIT_REPO="http://git.1080p.hk/chenpei/ai-chatbot.git"
|
||
GIT_USER="chenpei"
|
||
GIT_PASS="jsjj654321"
|
||
|
||
# 本地配置(仅用于数据库备份)
|
||
PROJECT_DIR="/Users/lanmu/Desktop/ai-chatbot-main"
|
||
BACKUP_DIR="$PROJECT_DIR/migration-backup-complete"
|
||
DB_BACKUP_FILE="$BACKUP_DIR/database_complete.dump"
|
||
|
||
# 服务器项目目录
|
||
SERVER_PROJECT_DIR="/var/www/ai-chatbot"
|
||
|
||
echo "=========================================="
|
||
echo "AI Chatbot 服务器迁移脚本"
|
||
echo "=========================================="
|
||
echo "新服务器: $NEW_USER@$NEW_SERVER:$NEW_PORT"
|
||
echo "域名: $DOMAIN"
|
||
echo "应用端口: $APP_PORT"
|
||
echo "从Git仓库拉取源码和备份数据库"
|
||
echo "时间: $(date)"
|
||
echo "=========================================="
|
||
echo ""
|
||
|
||
# 检查 sshpass 是否安装
|
||
if ! command -v sshpass &> /dev/null; then
|
||
echo "❌ sshpass 未安装,正在安装..."
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
brew install hudochenkov/sshpass/sshpass || echo "请手动安装: brew install hudochenkov/sshpass/sshpass"
|
||
else
|
||
sudo apt-get update && sudo apt-get install -y sshpass
|
||
fi
|
||
fi
|
||
|
||
# 检查本地备份文件
|
||
if [ ! -f "$DB_BACKUP_FILE" ]; then
|
||
echo "❌ 未找到数据库备份文件: $DB_BACKUP_FILE"
|
||
echo "请确保备份文件存在"
|
||
exit 1
|
||
fi
|
||
echo "✅ 找到数据库备份文件: $DB_BACKUP_FILE ($(du -h "$DB_BACKUP_FILE" | cut -f1))"
|
||
|
||
# 检查Git仓库配置
|
||
echo "✅ Git仓库: $GIT_REPO"
|
||
|
||
# SSH选项(保持连接)
|
||
SSH_OPTS="-o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o TCPKeepAlive=yes"
|
||
|
||
# 测试新服务器连接
|
||
echo ""
|
||
echo "🔍 测试新服务器连接..."
|
||
if sshpass -p "$NEW_PASS" ssh -p "$NEW_PORT" $SSH_OPTS "$NEW_USER@$NEW_SERVER" "echo '连接成功'" > /dev/null 2>&1; then
|
||
echo "✅ 新服务器连接正常"
|
||
else
|
||
echo "❌ 无法连接到新服务器"
|
||
exit 1
|
||
fi
|
||
|
||
# 步骤1: 在新服务器上安装必要软件
|
||
echo ""
|
||
echo "📦 步骤 1/8: 在新服务器上安装必要软件..."
|
||
sshpass -p "$NEW_PASS" ssh -p "$NEW_PORT" $SSH_OPTS "$NEW_USER@$NEW_SERVER" << 'INSTALLEOF'
|
||
set -e
|
||
|
||
echo "检测系统类型..."
|
||
if [ -f /etc/redhat-release ]; then
|
||
# CentOS/RHEL系统
|
||
echo "检测到CentOS/RHEL系统,使用dnf包管理器"
|
||
echo "跳过系统更新,直接安装所需软件..."
|
||
|
||
echo "安装基础工具..."
|
||
dnf install -y --nogpgcheck curl wget git gcc gcc-c++ make 2>&1 | tail -3 || dnf install -y curl wget git gcc gcc-c++ make 2>&1 | tail -3
|
||
|
||
echo "安装PostgreSQL..."
|
||
if ! command -v psql &> /dev/null; then
|
||
dnf install -y --nogpgcheck postgresql-server postgresql-contrib 2>&1 | tail -3 || dnf install -y postgresql-server postgresql-contrib 2>&1 | tail -3
|
||
postgresql-setup --initdb 2>/dev/null || /usr/bin/postgresql-setup --initdb || echo "⚠️ PostgreSQL初始化跳过"
|
||
systemctl start postgresql 2>/dev/null || true
|
||
systemctl enable postgresql 2>/dev/null || true
|
||
fi
|
||
|
||
echo "安装Node.js 20.x..."
|
||
echo "使用NodeSource安装Node.js 20..."
|
||
curl -fsSL https://rpm.nodesource.com/setup_20.x | bash -
|
||
dnf install -y --nogpgcheck nodejs 2>&1 | tail -3 || dnf install -y nodejs 2>&1 | tail -3
|
||
echo "Node.js安装完成"
|
||
|
||
echo "安装PM2和pnpm..."
|
||
if ! command -v pm2 &> /dev/null; then
|
||
npm install -g pm2
|
||
fi
|
||
if ! command -v pnpm &> /dev/null; then
|
||
npm install -g pnpm
|
||
fi
|
||
|
||
echo "安装Nginx..."
|
||
if ! command -v nginx &> /dev/null; then
|
||
dnf install -y --nogpgcheck nginx 2>&1 | tail -3 || dnf install -y nginx 2>&1 | tail -3
|
||
systemctl start nginx 2>/dev/null || true
|
||
systemctl enable nginx 2>/dev/null || true
|
||
fi
|
||
|
||
echo "安装Certbot (Let's Encrypt)..."
|
||
if ! command -v certbot &> /dev/null; then
|
||
# 安装EPEL仓库(CentOS需要)
|
||
dnf install -y --nogpgcheck epel-release 2>&1 | tail -2 || dnf install -y epel-release 2>&1 | tail -2
|
||
dnf install -y --nogpgcheck certbot python3-certbot-nginx 2>&1 | tail -3 || dnf install -y certbot python3-certbot-nginx 2>&1 | tail -3
|
||
fi
|
||
else
|
||
# Ubuntu/Debian系统
|
||
echo "检测到Ubuntu/Debian系统,使用apt-get包管理器"
|
||
echo "更新系统包..."
|
||
export DEBIAN_FRONTEND=noninteractive
|
||
apt-get update -qq
|
||
|
||
echo "安装基础工具..."
|
||
apt-get install -y -qq curl wget git build-essential software-properties-common
|
||
|
||
echo "安装PostgreSQL..."
|
||
if ! command -v psql &> /dev/null; then
|
||
apt-get install -y -qq postgresql postgresql-contrib
|
||
systemctl start postgresql
|
||
systemctl enable postgresql
|
||
fi
|
||
|
||
echo "安装Node.js 20.x..."
|
||
if ! command -v node &> /dev/null || [ "$(node -v | cut -d'v' -f2 | cut -d'.' -f1)" -lt 20 ]; then
|
||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||
apt-get install -y -qq nodejs
|
||
fi
|
||
|
||
echo "安装PM2和pnpm..."
|
||
if ! command -v pm2 &> /dev/null; then
|
||
npm install -g pm2
|
||
fi
|
||
if ! command -v pnpm &> /dev/null; then
|
||
npm install -g pnpm
|
||
fi
|
||
|
||
echo "安装Nginx..."
|
||
if ! command -v nginx &> /dev/null; then
|
||
apt-get install -y -qq nginx
|
||
systemctl start nginx
|
||
systemctl enable nginx
|
||
fi
|
||
|
||
echo "安装Certbot (Let's Encrypt)..."
|
||
if ! command -v certbot &> /dev/null; then
|
||
apt-get install -y -qq certbot python3-certbot-nginx
|
||
fi
|
||
fi
|
||
|
||
echo "✅ 所有软件安装完成"
|
||
INSTALLEOF
|
||
|
||
# 步骤2: 从Git仓库克隆项目
|
||
echo ""
|
||
echo "📥 步骤 2/8: 从Git仓库克隆项目..."
|
||
sshpass -p "$NEW_PASS" ssh -p "$NEW_PORT" $SSH_OPTS "$NEW_USER@$NEW_SERVER" << CLONEEOF
|
||
set -e
|
||
|
||
# 如果目录已存在,先删除
|
||
if [ -d "$SERVER_PROJECT_DIR" ]; then
|
||
echo "删除现有目录..."
|
||
rm -rf $SERVER_PROJECT_DIR
|
||
fi
|
||
|
||
# 从Git仓库克隆(使用用户名和密码)
|
||
echo "正在从Git仓库克隆..."
|
||
GIT_URL="http://${GIT_USER}:${GIT_PASS}@git.1080p.hk/chenpei/ai-chatbot.git"
|
||
git clone "\$GIT_URL" $SERVER_PROJECT_DIR || {
|
||
echo "⚠️ 使用URL中的凭据克隆失败,尝试直接使用凭据..."
|
||
git clone http://${GIT_USER}:${GIT_PASS}@git.1080p.hk/chenpei/ai-chatbot.git $SERVER_PROJECT_DIR
|
||
}
|
||
|
||
cd $SERVER_PROJECT_DIR
|
||
chown -R root:root .
|
||
echo "✅ 项目代码已从Git仓库克隆"
|
||
CLONEEOF
|
||
|
||
# 步骤3: 上传数据库备份
|
||
echo ""
|
||
echo "📤 步骤 3/8: 上传数据库备份..."
|
||
sshpass -p "$NEW_PASS" scp -P "$NEW_PORT" -o StrictHostKeyChecking=no -o ServerAliveInterval=60 "$DB_BACKUP_FILE" "$NEW_USER@$NEW_SERVER:/tmp/database.dump"
|
||
echo "✅ 数据库备份已上传"
|
||
|
||
# 步骤4: 创建数据库
|
||
echo ""
|
||
echo "🗄️ 步骤 4/8: 创建数据库..."
|
||
sshpass -p "$NEW_PASS" ssh -p "$NEW_PORT" $SSH_OPTS "$NEW_USER@$NEW_SERVER" << 'DBEOF'
|
||
set -e
|
||
|
||
# 生成随机数据库密码
|
||
DB_PASSWORD=$(openssl rand -base64 24 | tr -d "=+/" | cut -c1-25)
|
||
echo "生成的数据库密码: $DB_PASSWORD"
|
||
echo "$DB_PASSWORD" > /root/db_password.txt
|
||
|
||
# 启动PostgreSQL
|
||
systemctl start postgresql
|
||
|
||
# 创建数据库和用户
|
||
sudo -u postgres psql << PSQLEOF
|
||
-- 创建数据库(如果不存在)
|
||
SELECT 'CREATE DATABASE ai_chatbot'
|
||
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'ai_chatbot')\gexec
|
||
|
||
-- 创建用户(如果不存在)
|
||
DO \$\$
|
||
BEGIN
|
||
IF NOT EXISTS (SELECT FROM pg_user WHERE usename = 'chatbot_user') THEN
|
||
CREATE USER chatbot_user WITH PASSWORD '$DB_PASSWORD';
|
||
ELSE
|
||
ALTER USER chatbot_user WITH PASSWORD '$DB_PASSWORD';
|
||
END IF;
|
||
END
|
||
\$\$;
|
||
|
||
-- 授权
|
||
GRANT ALL PRIVILEGES ON DATABASE ai_chatbot TO chatbot_user;
|
||
ALTER DATABASE ai_chatbot OWNER TO chatbot_user;
|
||
PSQLEOF
|
||
|
||
echo "✅ 数据库创建完成"
|
||
DBEOF
|
||
|
||
# 步骤5: 配置环境变量和导入数据库
|
||
echo ""
|
||
echo "⚙️ 步骤 5/8: 配置环境变量和导入数据库..."
|
||
sshpass -p "$NEW_PASS" ssh -p "$NEW_PORT" $SSH_OPTS "$NEW_USER@$NEW_SERVER" << CONFIGEOF
|
||
set -e
|
||
cd /var/www/ai-chatbot
|
||
|
||
# 读取数据库密码
|
||
DB_PASSWORD=\$(cat /root/db_password.txt)
|
||
|
||
# 生成AUTH_SECRET
|
||
AUTH_SECRET=\$(openssl rand -base64 32)
|
||
|
||
# 创建环境变量文件
|
||
cat > .env.local << ENVFILE
|
||
POSTGRES_URL=postgresql://chatbot_user:\${DB_PASSWORD}@localhost:5432/ai_chatbot
|
||
AUTH_SECRET=\${AUTH_SECRET}
|
||
AUTH_URL=https://${DOMAIN}
|
||
NODE_ENV=production
|
||
PORT=${APP_PORT}
|
||
ENVFILE
|
||
|
||
echo "✅ 环境变量文件已创建"
|
||
|
||
# 导入数据库
|
||
echo "正在导入数据库..."
|
||
export PGPASSWORD="\$DB_PASSWORD"
|
||
pg_restore -h localhost -p 5432 -U chatbot_user -d ai_chatbot -c --no-owner --no-privileges /tmp/database.dump 2>&1 | grep -v -E "(already exists|does not exist|ERROR.*already)" || true
|
||
echo "✅ 数据库导入完成(已忽略重复项)"
|
||
|
||
# 安装依赖
|
||
echo "正在安装依赖..."
|
||
pnpm install --frozen-lockfile
|
||
echo "✅ 依赖安装完成"
|
||
|
||
# 运行数据库迁移(如果需要)
|
||
echo "正在运行数据库迁移..."
|
||
pnpm db:migrate || echo "⚠️ 数据库迁移跳过或失败"
|
||
echo "✅ 数据库迁移完成"
|
||
|
||
# 构建项目
|
||
echo "正在构建项目..."
|
||
pnpm build
|
||
echo "✅ 项目构建完成"
|
||
CONFIGEOF
|
||
|
||
# 步骤6: 配置PM2
|
||
echo ""
|
||
echo "🚀 步骤 6/8: 配置PM2..."
|
||
sshpass -p "$NEW_PASS" ssh -p "$NEW_PORT" $SSH_OPTS "$NEW_USER@$NEW_SERVER" << 'PM2EOF'
|
||
set -e
|
||
cd /var/www/ai-chatbot
|
||
|
||
# 创建PM2配置文件
|
||
cat > ecosystem.config.js << 'PM2CONFIG'
|
||
module.exports = {
|
||
apps: [{
|
||
name: 'ai-chatbot',
|
||
script: 'node_modules/next/dist/bin/next',
|
||
args: 'start',
|
||
cwd: '/var/www/ai-chatbot',
|
||
instances: 1,
|
||
exec_mode: 'fork',
|
||
env: {
|
||
NODE_ENV: 'production',
|
||
PORT: 3125
|
||
},
|
||
error_file: '/var/log/pm2/ai-chatbot-error.log',
|
||
out_file: '/var/log/pm2/ai-chatbot-out.log',
|
||
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
||
merge_logs: true,
|
||
autorestart: true,
|
||
max_memory_restart: '1G'
|
||
}]
|
||
};
|
||
PM2CONFIG
|
||
|
||
# 创建日志目录
|
||
mkdir -p /var/log/pm2
|
||
|
||
# 启动应用
|
||
pm2 delete ai-chatbot 2>/dev/null || true
|
||
pm2 start ecosystem.config.js
|
||
pm2 save
|
||
pm2 startup systemd -u root --hp /root || true
|
||
|
||
echo "✅ PM2 配置完成"
|
||
PM2EOF
|
||
|
||
# 步骤7: 配置Nginx(HTTP,稍后配置HTTPS)
|
||
echo ""
|
||
echo "🌐 步骤 7/8: 配置Nginx..."
|
||
sshpass -p "$NEW_PASS" ssh -p "$NEW_PORT" $SSH_OPTS "$NEW_USER@$NEW_SERVER" << 'NGINXEOF'
|
||
set -e
|
||
|
||
DOMAIN="ai.yydd.ai"
|
||
APP_PORT="3125"
|
||
|
||
# 创建Nginx配置(HTTP,用于Certbot验证)
|
||
cat > /etc/nginx/sites-available/ai-chatbot << 'NGINXCONFIG'
|
||
server {
|
||
listen 80;
|
||
server_name ai.yydd.ai;
|
||
|
||
# 关闭缓存
|
||
proxy_cache off;
|
||
proxy_buffering off;
|
||
proxy_no_cache 1;
|
||
proxy_cache_bypass 1;
|
||
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
|
||
add_header Pragma "no-cache";
|
||
add_header Expires "0";
|
||
|
||
location / {
|
||
proxy_pass http://localhost:3125;
|
||
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;
|
||
proxy_read_timeout 300s;
|
||
proxy_connect_timeout 75s;
|
||
|
||
# 禁用缓存
|
||
proxy_set_header Cache-Control "no-cache, no-store, must-revalidate";
|
||
}
|
||
}
|
||
NGINXCONFIG
|
||
|
||
# 启用站点
|
||
ln -sf /etc/nginx/sites-available/ai-chatbot /etc/nginx/sites-enabled/
|
||
rm -f /etc/nginx/sites-enabled/default
|
||
|
||
# 测试配置
|
||
nginx -t
|
||
|
||
# 重载Nginx
|
||
systemctl reload nginx
|
||
|
||
echo "✅ Nginx HTTP配置完成"
|
||
NGINXEOF
|
||
|
||
# 步骤8: 配置HTTPS和强制HTTPS
|
||
echo ""
|
||
echo "🔒 步骤 8/8: 配置HTTPS证书和强制HTTPS..."
|
||
sshpass -p "$NEW_PASS" ssh -p "$NEW_PORT" $SSH_OPTS "$NEW_USER@$NEW_SERVER" << 'HTTPSEOF'
|
||
set -e
|
||
|
||
DOMAIN="ai.yydd.ai"
|
||
APP_PORT="3125"
|
||
|
||
# 获取Let's Encrypt证书
|
||
echo "正在获取SSL证书..."
|
||
certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --email admin@yydd.ai --redirect || {
|
||
echo "⚠️ Certbot执行失败,可能需要手动配置"
|
||
echo "手动运行: certbot --nginx -d $DOMAIN"
|
||
}
|
||
|
||
# 更新Nginx配置以强制HTTPS和关闭缓存
|
||
cat > /etc/nginx/sites-available/ai-chatbot << 'NGINXHTTPS'
|
||
# HTTP重定向到HTTPS
|
||
server {
|
||
listen 80;
|
||
server_name ai.yydd.ai;
|
||
return 301 https://$server_name$request_uri;
|
||
}
|
||
|
||
# HTTPS配置
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name ai.yydd.ai;
|
||
|
||
# SSL证书配置(Certbot会自动添加)
|
||
ssl_certificate /etc/letsencrypt/live/ai.yydd.ai/fullchain.pem;
|
||
ssl_certificate_key /etc/letsencrypt/live/ai.yydd.ai/privkey.pem;
|
||
|
||
# SSL优化配置
|
||
ssl_protocols TLSv1.2 TLSv1.3;
|
||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||
ssl_prefer_server_ciphers on;
|
||
ssl_session_cache shared:SSL:10m;
|
||
ssl_session_timeout 10m;
|
||
|
||
# 关闭缓存
|
||
proxy_cache off;
|
||
proxy_buffering off;
|
||
proxy_no_cache 1;
|
||
proxy_cache_bypass 1;
|
||
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
|
||
add_header Pragma "no-cache" always;
|
||
add_header Expires "0" always;
|
||
|
||
location / {
|
||
proxy_pass http://localhost:3125;
|
||
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;
|
||
proxy_read_timeout 300s;
|
||
proxy_connect_timeout 75s;
|
||
|
||
# 禁用缓存
|
||
proxy_set_header Cache-Control "no-cache, no-store, must-revalidate";
|
||
proxy_hide_header Cache-Control;
|
||
proxy_hide_header Expires;
|
||
}
|
||
}
|
||
NGINXHTTPS
|
||
|
||
# 测试配置
|
||
nginx -t && systemctl reload nginx
|
||
|
||
echo "✅ HTTPS配置完成"
|
||
HTTPSEOF
|
||
|
||
# 清理临时文件
|
||
echo ""
|
||
echo "🧹 清理临时文件..."
|
||
sshpass -p "$NEW_PASS" ssh -p "$NEW_PORT" $SSH_OPTS "$NEW_USER@$NEW_SERVER" "rm -f /tmp/project.tar.gz /tmp/database.dump"
|
||
|
||
echo ""
|
||
echo "=========================================="
|
||
echo "✅ 迁移完成!"
|
||
echo "=========================================="
|
||
echo "新服务器地址: https://$DOMAIN"
|
||
echo "应用端口: $APP_PORT"
|
||
echo ""
|
||
echo "📝 重要信息:"
|
||
echo "数据库密码已保存在: /root/db_password.txt"
|
||
echo ""
|
||
echo "🔍 验证步骤:"
|
||
echo "1. 检查PM2状态: ssh -p $NEW_PORT $NEW_USER@$NEW_SERVER 'pm2 status'"
|
||
echo "2. 检查日志: ssh -p $NEW_PORT $NEW_USER@$NEW_SERVER 'pm2 logs ai-chatbot'"
|
||
echo "3. 检查Nginx状态: ssh -p $NEW_PORT $NEW_USER@$NEW_SERVER 'systemctl status nginx'"
|
||
echo "4. 检查SSL证书: ssh -p $NEW_PORT $NEW_USER@$NEW_SERVER 'certbot certificates'"
|
||
echo "5. 访问网站: https://$DOMAIN"
|
||
echo ""
|
||
echo "⚠️ 注意事项:"
|
||
echo "- 如果Certbot失败,请手动运行: certbot --nginx -d $DOMAIN"
|
||
echo "- 确保域名 $DOMAIN 的DNS已指向 $NEW_SERVER"
|
||
echo "- 检查防火墙是否开放80和443端口"
|
||
echo "=========================================="
|
||
|