304 lines
8.2 KiB
Bash
Executable File
304 lines
8.2 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# 自动部署脚本 - 包含密码
|
||
# 使用方法: ./auto-deploy.sh
|
||
|
||
set -e
|
||
|
||
# 服务器配置
|
||
SERVER="156.225.27.52"
|
||
PORT="5204"
|
||
USER="root"
|
||
PASSWORD="${DEPLOY_SSH_PASSWORD:?set DEPLOY_SSH_PASSWORD}"
|
||
REMOTE_DIR="/var/www/ai-chatbot"
|
||
|
||
# 颜色输出
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
NC='\033[0m'
|
||
|
||
echo -e "${GREEN}开始自动部署到服务器...${NC}"
|
||
|
||
# 检查是否安装了 sshpass
|
||
if ! command -v sshpass &> /dev/null; then
|
||
echo -e "${YELLOW}安装 sshpass...${NC}"
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
# macOS
|
||
if ! command -v brew &> /dev/null; then
|
||
echo -e "${RED}请先安装 Homebrew: /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"${NC}"
|
||
exit 1
|
||
fi
|
||
brew install hudochenkov/sshpass/sshpass
|
||
else
|
||
# Linux
|
||
sudo apt-get update && sudo apt-get install -y sshpass
|
||
fi
|
||
fi
|
||
|
||
# SSH 连接函数
|
||
ssh_cmd() {
|
||
sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -p $PORT $USER@$SERVER "$1"
|
||
}
|
||
|
||
scp_cmd() {
|
||
sshpass -p "$PASSWORD" scp -o StrictHostKeyChecking=no -P $PORT "$1" $USER@$SERVER:"$2"
|
||
}
|
||
|
||
scp_dir() {
|
||
sshpass -p "$PASSWORD" scp -o StrictHostKeyChecking=no -P $PORT -r "$1" $USER@$SERVER:"$2"
|
||
}
|
||
|
||
echo -e "${GREEN}步骤 1: 检查服务器连接...${NC}"
|
||
ssh_cmd "echo '连接成功' && uname -a"
|
||
|
||
echo -e "${GREEN}步骤 2: 检查并安装必要软件...${NC}"
|
||
ssh_cmd "
|
||
# 检查 Node.js
|
||
if ! command -v node &> /dev/null; then
|
||
echo '安装 Node.js...'
|
||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
|
||
export NVM_DIR=\"\$HOME/.nvm\"
|
||
[ -s \"\$NVM_DIR/nvm.sh\" ] && . \"\$NVM_DIR/nvm.sh\"
|
||
nvm install 20
|
||
nvm use 20
|
||
nvm alias default 20
|
||
fi
|
||
|
||
# 检查 pnpm
|
||
if ! command -v pnpm &> /dev/null; then
|
||
echo '安装 pnpm...'
|
||
npm install -g pnpm
|
||
fi
|
||
|
||
# 检查 PM2
|
||
if ! command -v pm2 &> /dev/null; then
|
||
echo '安装 PM2...'
|
||
npm install -g pm2
|
||
fi
|
||
|
||
# 检查 PostgreSQL
|
||
if ! command -v psql &> /dev/null; then
|
||
echo '安装 PostgreSQL...'
|
||
apt-get update -y
|
||
apt-get install -y postgresql postgresql-contrib
|
||
systemctl start postgresql
|
||
systemctl enable postgresql
|
||
fi
|
||
|
||
# 检查 Nginx
|
||
if ! command -v nginx &> /dev/null; then
|
||
echo '安装 Nginx...'
|
||
apt-get install -y nginx
|
||
systemctl start nginx
|
||
systemctl enable nginx
|
||
fi
|
||
|
||
# 创建项目目录
|
||
mkdir -p $REMOTE_DIR
|
||
mkdir -p /var/log/pm2
|
||
mkdir -p /root/backups/ai-chatbot
|
||
"
|
||
|
||
echo -e "${GREEN}步骤 3: 配置数据库...${NC}"
|
||
ssh_cmd "
|
||
# 检查并创建/更新数据库用户
|
||
echo '配置数据库用户...'
|
||
sudo -u postgres psql << 'PSQL'
|
||
-- 删除已存在的用户(如果存在)
|
||
DROP USER IF EXISTS chatbot_user;
|
||
|
||
-- 创建新用户
|
||
CREATE USER chatbot_user WITH PASSWORD 'ChatBot@2024!Secure';
|
||
|
||
-- 检查数据库是否存在
|
||
SELECT 1 FROM pg_database WHERE datname='ai_chatbot'\\gexec
|
||
|
||
-- 如果不存在则创建
|
||
DO \\$\\$
|
||
BEGIN
|
||
IF NOT EXISTS (SELECT FROM pg_database WHERE datname = 'ai_chatbot') THEN
|
||
CREATE DATABASE ai_chatbot;
|
||
END IF;
|
||
END
|
||
\\$\\$;
|
||
|
||
-- 授予权限
|
||
GRANT ALL PRIVILEGES ON DATABASE ai_chatbot TO chatbot_user;
|
||
|
||
-- 连接到数据库并授予schema权限
|
||
\\c ai_chatbot
|
||
GRANT ALL ON SCHEMA public TO chatbot_user;
|
||
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO chatbot_user;
|
||
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO chatbot_user;
|
||
|
||
\\q
|
||
PSQL
|
||
echo '数据库配置完成'
|
||
"
|
||
|
||
echo -e "${GREEN}步骤 4: 上传项目文件...${NC}"
|
||
# 创建临时部署包
|
||
echo "准备部署文件..."
|
||
tar --exclude='node_modules' \
|
||
--exclude='.next' \
|
||
--exclude='.git' \
|
||
--exclude='.env.local' \
|
||
--exclude='*.log' \
|
||
--exclude='deploy.tar.gz' \
|
||
-czf /tmp/deploy.tar.gz .
|
||
|
||
# 上传部署包
|
||
scp_cmd "/tmp/deploy.tar.gz" "/tmp/"
|
||
|
||
# 在服务器上解压
|
||
ssh_cmd "
|
||
cd $REMOTE_DIR
|
||
tar -xzf /tmp/deploy.tar.gz
|
||
rm /tmp/deploy.tar.gz
|
||
|
||
if [ -f \"$REMOTE_DIR/scripts/security/install-security-stack.sh\" ]; then
|
||
echo '安装 security-stack...'
|
||
bash \"$REMOTE_DIR/scripts/security/install-security-stack.sh\" || echo 'security-stack 安装失败,继续部署'
|
||
elif [ -f \"$REMOTE_DIR/scripts/security/install-perf-guard.sh\" ]; then
|
||
echo '安装 perf-guard...'
|
||
bash \"$REMOTE_DIR/scripts/security/install-perf-guard.sh\" || echo 'perf-guard 安装失败,继续部署'
|
||
fi
|
||
"
|
||
|
||
echo -e "${GREEN}步骤 5: 配置环境变量...${NC}"
|
||
ssh_cmd "
|
||
cd $REMOTE_DIR
|
||
|
||
# 生成 AUTH_SECRET
|
||
AUTH_SECRET=\$(openssl rand -base64 32)
|
||
|
||
# 创建 .env.local 文件
|
||
cat > .env.local << EOF
|
||
POSTGRES_URL=postgresql://chatbot_user:ChatBot@2024!Secure@localhost:5432/ai_chatbot
|
||
AUTH_SECRET=\$AUTH_SECRET
|
||
AUTH_URL=http://$SERVER
|
||
NODE_ENV=production
|
||
EOF
|
||
|
||
echo '环境变量文件已创建'
|
||
"
|
||
|
||
echo -e "${GREEN}步骤 6: 安装依赖和构建...${NC}"
|
||
ssh_cmd "
|
||
cd $REMOTE_DIR
|
||
export NVM_DIR=\"\$HOME/.nvm\"
|
||
[ -s \"\$NVM_DIR/nvm.sh\" ] && . \"\$NVM_DIR/nvm.sh\"
|
||
|
||
echo '安装依赖...'
|
||
pnpm install --production=false
|
||
|
||
echo '运行数据库迁移...'
|
||
pnpm db:migrate || echo '迁移可能已存在,继续...'
|
||
|
||
echo '构建项目...'
|
||
pnpm build
|
||
"
|
||
|
||
echo -e "${GREEN}步骤 7: 配置 PM2...${NC}"
|
||
# 上传 PM2 配置文件
|
||
scp_cmd "ecosystem.config.js" "$REMOTE_DIR/"
|
||
|
||
ssh_cmd "
|
||
cd $REMOTE_DIR
|
||
export NVM_DIR=\"\$HOME/.nvm\"
|
||
[ -s \"\$NVM_DIR/nvm.sh\" ] && . \"\$NVM_DIR/nvm.sh\"
|
||
|
||
# 停止旧进程(如果存在)
|
||
pm2 delete ai-chatbot 2>/dev/null || true
|
||
|
||
# 启动应用
|
||
pm2 start ecosystem.config.js
|
||
pm2 save
|
||
|
||
# 设置开机自启
|
||
pm2 startup systemd -u root --hp /root 2>/dev/null || echo 'PM2 startup 已配置'
|
||
"
|
||
|
||
echo -e "${GREEN}步骤 8: 配置 Nginx...${NC}"
|
||
ssh_cmd "
|
||
# 创建 Nginx 配置
|
||
cat > /etc/nginx/sites-available/ai-chatbot << 'NGINX'
|
||
server {
|
||
listen 80;
|
||
server_name $SERVER;
|
||
|
||
location / {
|
||
proxy_pass http://localhost:3000;
|
||
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;
|
||
}
|
||
}
|
||
NGINX
|
||
|
||
# 启用站点
|
||
ln -sf /etc/nginx/sites-available/ai-chatbot /etc/nginx/sites-enabled/
|
||
|
||
# 删除默认配置(如果存在)
|
||
rm -f /etc/nginx/sites-enabled/default
|
||
|
||
# 测试配置
|
||
nginx -t
|
||
|
||
# 重启 Nginx
|
||
systemctl restart nginx
|
||
"
|
||
|
||
echo -e "${GREEN}步骤 9: 配置防火墙...${NC}"
|
||
ssh_cmd "
|
||
ufw --force enable
|
||
ufw allow 80/tcp
|
||
ufw allow 443/tcp
|
||
ufw allow 5204/tcp
|
||
ufw allow 3000/tcp
|
||
"
|
||
|
||
echo -e "${GREEN}步骤 10: 检查部署状态...${NC}"
|
||
ssh_cmd "
|
||
echo '=== PM2 状态 ==='
|
||
pm2 status
|
||
|
||
echo ''
|
||
echo '=== 应用日志(最后20行)==='
|
||
pm2 logs ai-chatbot --lines 20 --nostream
|
||
|
||
echo ''
|
||
echo '=== Nginx 状态 ==='
|
||
systemctl status nginx --no-pager -l
|
||
|
||
echo ''
|
||
echo '=== 端口监听 ==='
|
||
netstat -tulpn | grep -E ':(80|3000|5432)' || ss -tulpn | grep -E ':(80|3000|5432)'
|
||
"
|
||
|
||
# 清理本地临时文件
|
||
rm -f /tmp/deploy.tar.gz
|
||
|
||
echo -e "${GREEN}========================================${NC}"
|
||
echo -e "${GREEN}部署完成!${NC}"
|
||
echo -e "${GREEN}========================================${NC}"
|
||
echo -e "${YELLOW}访问地址: http://$SERVER${NC}"
|
||
echo -e "${YELLOW}管理员设置: http://$SERVER/admin/settings${NC}"
|
||
echo -e "${YELLOW}查看日志: ssh -p $PORT $USER@$SERVER 'pm2 logs ai-chatbot'${NC}"
|
||
echo -e "${YELLOW}查看状态: ssh -p $PORT $USER@$SERVER 'pm2 status'${NC}"
|
||
echo ""
|
||
echo -e "${YELLOW}数据库信息:${NC}"
|
||
echo -e " 数据库名: ai_chatbot"
|
||
echo -e " 用户名: chatbot_user"
|
||
echo -e " 密码: ChatBot@2024!Secure"
|
||
echo ""
|
||
echo -e "${YELLOW}注意: 请尽快修改数据库密码和服务器密码!${NC}"
|