513 lines
12 KiB
Bash
Executable File
513 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
###############################################################################
|
||
# DesignHub 公网服务器自动化部署脚本
|
||
# 服务器: 45.192.99.48
|
||
# 使用方法: bash deploy_to_public_server.sh
|
||
###############################################################################
|
||
|
||
set -e
|
||
|
||
# 颜色定义
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
# 服务器配置
|
||
SERVER_IP="45.192.99.48"
|
||
SERVER_PORT="22"
|
||
SERVER_USER="root"
|
||
SERVER_PASSWORD="1blZllMIp7"
|
||
|
||
# 应用配置
|
||
APP_NAME="designhub"
|
||
APP_DIR="/opt/${APP_NAME}"
|
||
DB_NAME="designhub"
|
||
DB_USER="designhub"
|
||
DB_PASSWORD="DesignHub@2025_DB"
|
||
REDIS_PASSWORD="DesignHub@2025_Redis"
|
||
MYSQL_ROOT_PASSWORD="DesignHub@2025_Root"
|
||
|
||
echo "========================================"
|
||
echo -e "${GREEN} DesignHub 公网服务器部署脚本${NC}"
|
||
echo "========================================"
|
||
echo ""
|
||
echo "服务器信息:"
|
||
echo " IP: ${SERVER_IP}"
|
||
echo " 端口: ${SERVER_PORT}"
|
||
echo " 用户: ${SERVER_USER}"
|
||
echo ""
|
||
|
||
# 检查 sshpass 是否安装
|
||
check_sshpass() {
|
||
if ! command -v sshpass &> /dev/null; then
|
||
echo -e "${YELLOW}正在安装 sshpass...${NC}"
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
brew install hudochenkov/sshpass/sshpass 2>/dev/null || {
|
||
echo -e "${RED}请先安装 sshpass: brew install hudochenkov/sshpass/sshpass${NC}"
|
||
exit 1
|
||
}
|
||
else
|
||
sudo apt-get install -y sshpass 2>/dev/null || sudo yum install -y sshpass 2>/dev/null
|
||
fi
|
||
fi
|
||
echo -e "${GREEN}✓ sshpass 已就绪${NC}"
|
||
}
|
||
|
||
# SSH 命令封装
|
||
ssh_cmd() {
|
||
sshpass -p "${SERVER_PASSWORD}" ssh -p ${SERVER_PORT} \
|
||
-o StrictHostKeyChecking=no \
|
||
-o UserKnownHostsFile=/dev/null \
|
||
-o ConnectTimeout=30 \
|
||
${SERVER_USER}@${SERVER_IP} "$@"
|
||
}
|
||
|
||
# SCP 命令封装
|
||
scp_cmd() {
|
||
sshpass -p "${SERVER_PASSWORD}" scp -P ${SERVER_PORT} \
|
||
-o StrictHostKeyChecking=no \
|
||
-o UserKnownHostsFile=/dev/null \
|
||
"$@"
|
||
}
|
||
|
||
# rsync 命令封装
|
||
rsync_cmd() {
|
||
sshpass -p "${SERVER_PASSWORD}" rsync -avz \
|
||
-e "ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
|
||
"$@"
|
||
}
|
||
|
||
# 测试连接
|
||
test_connection() {
|
||
echo -e "${BLUE}[0/10] 测试服务器连接...${NC}"
|
||
if ssh_cmd "echo 'Connection successful'" 2>/dev/null; then
|
||
echo -e "${GREEN}✓ 服务器连接成功${NC}"
|
||
else
|
||
echo -e "${RED}✗ 无法连接到服务器${NC}"
|
||
exit 1
|
||
fi
|
||
echo ""
|
||
}
|
||
|
||
# 步骤1:安装系统依赖
|
||
install_dependencies() {
|
||
echo -e "${BLUE}[1/10] 安装系统依赖...${NC}"
|
||
|
||
ssh_cmd << 'ENDSSH'
|
||
set -e
|
||
|
||
# 安装基础工具
|
||
echo "安装基础工具..."
|
||
dnf install -y -q curl wget git unzip
|
||
|
||
# 检查并安装 Java 17
|
||
if ! command -v java &> /dev/null || ! java -version 2>&1 | grep -q "17"; then
|
||
echo "安装 Java 17..."
|
||
dnf install -y -q java-17-openjdk java-17-openjdk-devel
|
||
fi
|
||
|
||
# 检查并安装 Maven
|
||
if ! command -v mvn &> /dev/null; then
|
||
echo "安装 Maven..."
|
||
dnf install -y -q maven
|
||
fi
|
||
|
||
# 检查并安装 MySQL
|
||
if ! command -v mysql &> /dev/null; then
|
||
echo "安装 MySQL..."
|
||
dnf install -y -q mysql-server mysql
|
||
systemctl enable mysqld
|
||
systemctl start mysqld
|
||
sleep 3
|
||
# 设置root密码
|
||
mysqladmin -u root password "${MYSQL_ROOT_PASSWORD}" 2>/dev/null || mysqladmin -u root password "${MYSQL_ROOT_PASSWORD}"
|
||
fi
|
||
|
||
# 检查并安装 Redis
|
||
if ! command -v redis-cli &> /dev/null; then
|
||
echo "安装 Redis..."
|
||
dnf install -y -q redis
|
||
systemctl enable redis
|
||
systemctl start redis
|
||
fi
|
||
|
||
# Nginx 已安装,检查状态
|
||
systemctl enable nginx || true
|
||
systemctl start nginx || true
|
||
|
||
# Node.js 和 pnpm 已安装,跳过
|
||
|
||
echo "✓ 系统依赖安装完成"
|
||
ENDSSH
|
||
|
||
echo -e "${GREEN}✓ 系统依赖安装完成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 步骤2:创建目录结构
|
||
create_directories() {
|
||
echo -e "${BLUE}[2/10] 创建目录结构...${NC}"
|
||
|
||
ssh_cmd << ENDSSH
|
||
set -e
|
||
mkdir -p ${APP_DIR}/{backend,frontend,logs,uploads}
|
||
mkdir -p /etc/nginx/conf.d
|
||
echo "✓ 目录创建完成"
|
||
ENDSSH
|
||
|
||
echo -e "${GREEN}✓ 目录结构创建完成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 步骤3:配置 MySQL
|
||
setup_mysql() {
|
||
echo -e "${BLUE}[3/10] 配置 MySQL 数据库...${NC}"
|
||
|
||
ssh_cmd << ENDSSH
|
||
set -e
|
||
|
||
# 启动 MySQL (CentOS使用mysqld)
|
||
systemctl start mysqld || true
|
||
systemctl enable mysqld || true
|
||
|
||
# 等待MySQL启动
|
||
sleep 5
|
||
|
||
# 创建数据库和用户
|
||
mysql -uroot -p${MYSQL_ROOT_PASSWORD} << 'EOSQL' 2>/dev/null || mysql -uroot -p${MYSQL_ROOT_PASSWORD} << 'EOSQL'
|
||
CREATE DATABASE IF NOT EXISTS ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||
CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
|
||
GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
|
||
FLUSH PRIVILEGES;
|
||
EOSQL
|
||
|
||
echo "✓ MySQL 配置完成"
|
||
ENDSSH
|
||
|
||
echo -e "${GREEN}✓ MySQL 配置完成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 步骤4:配置 Redis
|
||
setup_redis() {
|
||
echo -e "${BLUE}[4/10] 配置 Redis...${NC}"
|
||
|
||
ssh_cmd << ENDSSH
|
||
set -e
|
||
|
||
# 启动 Redis (CentOS使用redis服务)
|
||
systemctl start redis || true
|
||
systemctl enable redis || true
|
||
|
||
# 设置密码(如果还没设置)
|
||
redis-cli CONFIG SET requirepass "${REDIS_PASSWORD}" 2>/dev/null || true
|
||
|
||
echo "✓ Redis 配置完成"
|
||
ENDSSH
|
||
|
||
echo -e "${GREEN}✓ Redis 配置完成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 步骤5:上传后端代码
|
||
upload_backend() {
|
||
echo -e "${BLUE}[5/10] 上传后端代码...${NC}"
|
||
|
||
# 上传整个backend目录
|
||
rsync_cmd --exclude='target' --exclude='*.class' \
|
||
backend/ ${SERVER_USER}@${SERVER_IP}:${APP_DIR}/backend/
|
||
|
||
echo -e "${GREEN}✓ 后端代码上传完成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 步骤6:上传前端代码
|
||
upload_frontend() {
|
||
echo -e "${BLUE}[6/10] 上传前端代码...${NC}"
|
||
|
||
# 上传整个frontend目录(不包括node_modules)
|
||
rsync_cmd --exclude='node_modules' --exclude='dist' \
|
||
frontend/ ${SERVER_USER}@${SERVER_IP}:${APP_DIR}/frontend/
|
||
|
||
echo -e "${GREEN}✓ 前端代码上传完成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 步骤7:配置后端
|
||
setup_backend() {
|
||
echo -e "${BLUE}[7/10] 配置并构建后端...${NC}"
|
||
|
||
ssh_cmd << ENDSSH
|
||
set -e
|
||
cd ${APP_DIR}/backend
|
||
|
||
# 创建生产环境配置文件
|
||
cat > src/main/resources/application-prod.yml << EOF
|
||
spring:
|
||
datasource:
|
||
url: jdbc:mysql://localhost:3306/${DB_NAME}?useUnicode=true&characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||
username: ${DB_USER}
|
||
password: ${DB_PASSWORD}
|
||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||
hikari:
|
||
minimum-idle: 10
|
||
maximum-pool-size: 50
|
||
connection-timeout: 30000
|
||
idle-timeout: 600000
|
||
max-lifetime: 1800000
|
||
|
||
redis:
|
||
host: localhost
|
||
port: 6379
|
||
password: ${REDIS_PASSWORD}
|
||
database: 0
|
||
timeout: 3000
|
||
|
||
jwt:
|
||
secret: DesignHub_Prod_Secret_Key_2025_Very_Strong
|
||
access-token-expiration: 7200000
|
||
refresh-token-expiration: 604800000
|
||
|
||
server:
|
||
port: 5123
|
||
|
||
logging:
|
||
level:
|
||
root: INFO
|
||
com.designhub: INFO
|
||
file:
|
||
name: ${APP_DIR}/logs/application.log
|
||
max-size: 10MB
|
||
max-history: 30
|
||
|
||
file:
|
||
upload:
|
||
path: ${APP_DIR}/uploads
|
||
max-size: 52428800
|
||
EOF
|
||
|
||
# 构建项目
|
||
echo "开始构建后端项目..."
|
||
mvn clean package -DskipTests 2>&1 | tail -20
|
||
|
||
# 复制 JAR 文件
|
||
cp target/designhub-backend-1.0.0.jar ${APP_DIR}/designhub.jar
|
||
|
||
echo "✓ 后端构建完成"
|
||
ENDSSH
|
||
|
||
echo -e "${GREEN}✓ 后端配置完成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 步骤8:配置前端
|
||
setup_frontend() {
|
||
echo -e "${BLUE}[8/10] 配置并构建前端...${NC}"
|
||
|
||
ssh_cmd << ENDSSH
|
||
set -e
|
||
cd ${APP_DIR}/frontend
|
||
|
||
# 创建生产环境配置
|
||
cat > .env.production << EOF
|
||
VITE_APP_BASE_API=http://${SERVER_IP}/api
|
||
VITE_APP_TITLE=DesignHub
|
||
VITE_APP_VERSION=6.0
|
||
EOF
|
||
|
||
# 安装依赖
|
||
echo "安装前端依赖..."
|
||
pnpm install
|
||
|
||
# 构建项目
|
||
echo "构建前端项目..."
|
||
pnpm build
|
||
|
||
echo "✓ 前端构建完成"
|
||
ENDSSH
|
||
|
||
echo -e "${GREEN}✓ 前端配置完成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 步骤9:配置系统服务
|
||
setup_services() {
|
||
echo -e "${BLUE}[9/10] 配置系统服务...${NC}"
|
||
|
||
ssh_cmd << ENDSSH
|
||
set -e
|
||
|
||
# 配置防火墙开放5123端口
|
||
if command -v firewall-cmd &> /dev/null; then
|
||
firewall-cmd --permanent --add-port=5123/tcp
|
||
firewall-cmd --reload
|
||
echo "✓ 防火墙端口5123已开放"
|
||
elif command -v ufw &> /dev/null; then
|
||
ufw allow 5123/tcp
|
||
echo "✓ 防火墙端口5123已开放"
|
||
else
|
||
echo "未找到防火墙工具,请手动开放端口5123"
|
||
fi
|
||
|
||
# 创建后端服务
|
||
cat > /etc/systemd/system/designhub-backend.service << EOF
|
||
[Unit]
|
||
Description=DesignHub Backend Service
|
||
After=network.target mysqld.service redis.service
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=root
|
||
WorkingDirectory=${APP_DIR}
|
||
ExecStart=/usr/bin/java -Xms512m -Xmx1024m -jar ${APP_DIR}/designhub.jar --spring.profiles.active=prod --server.address=127.0.0.1
|
||
Restart=on-failure
|
||
RestartSec=10
|
||
|
||
StandardOutput=append:${APP_DIR}/logs/backend.log
|
||
StandardError=append:${APP_DIR}/logs/backend-error.log
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
# 统一旧服务名 designhub 到同一份 systemd 单元,避免双服务互相抢占 5123 端口
|
||
if [ -f /etc/systemd/system/designhub.service ] && [ ! -L /etc/systemd/system/designhub.service ]; then
|
||
mv /etc/systemd/system/designhub.service /etc/systemd/system/designhub.service.bak.$(date +%Y%m%d_%H%M%S)
|
||
fi
|
||
ln -sfn /etc/systemd/system/designhub-backend.service /etc/systemd/system/designhub.service
|
||
|
||
# 创建 Nginx 配置
|
||
cat > /etc/nginx/conf.d/designhub.conf << EOF
|
||
server {
|
||
listen 80;
|
||
server_name ${SERVER_IP};
|
||
|
||
root ${APP_DIR}/frontend/dist;
|
||
index index.html;
|
||
|
||
access_log ${APP_DIR}/logs/nginx-access.log;
|
||
error_log ${APP_DIR}/logs/nginx-error.log;
|
||
|
||
# 前端路由
|
||
location / {
|
||
try_files \$uri \$uri/ /index.html;
|
||
}
|
||
|
||
# API 代理
|
||
location /api/ {
|
||
proxy_pass http://localhost:5123/api/;
|
||
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_connect_timeout 600;
|
||
proxy_send_timeout 600;
|
||
proxy_read_timeout 600;
|
||
}
|
||
|
||
# 静态资源缓存
|
||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||
expires 30d;
|
||
add_header Cache-Control "public, immutable";
|
||
}
|
||
|
||
gzip on;
|
||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
|
||
gzip_min_length 1000;
|
||
}
|
||
EOF
|
||
|
||
# 重新加载 systemd
|
||
systemctl daemon-reload
|
||
|
||
# 测试 Nginx 配置
|
||
nginx -t
|
||
|
||
# 重启 Nginx
|
||
systemctl restart nginx
|
||
systemctl enable nginx
|
||
|
||
echo "✓ 系统服务配置完成"
|
||
ENDSSH
|
||
|
||
echo -e "${GREEN}✓ 系统服务配置完成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 步骤10:启动服务
|
||
start_services() {
|
||
echo -e "${BLUE}[10/10] 启动服务...${NC}"
|
||
|
||
ssh_cmd << ENDSSH
|
||
set -e
|
||
|
||
# 启动后端服务
|
||
systemctl start designhub-backend
|
||
systemctl enable designhub-backend
|
||
|
||
# 等待服务启动
|
||
sleep 5
|
||
|
||
# 检查服务状态
|
||
echo ""
|
||
echo "=== 服务状态 ==="
|
||
systemctl status designhub-backend --no-pager -l | head -15
|
||
|
||
echo ""
|
||
echo "✓ 服务启动完成"
|
||
ENDSSH
|
||
|
||
echo -e "${GREEN}✓ 服务启动完成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 显示部署信息
|
||
show_deployment_info() {
|
||
echo ""
|
||
echo "========================================"
|
||
echo -e "${GREEN} 部署完成!${NC}"
|
||
echo "========================================"
|
||
echo ""
|
||
echo "访问地址:"
|
||
echo " http://${SERVER_IP}"
|
||
echo ""
|
||
echo "API 地址:"
|
||
echo " http://${SERVER_IP}/api"
|
||
echo ""
|
||
echo "服务管理:"
|
||
echo " 查看后端状态: ssh ${SERVER_USER}@${SERVER_IP} 'systemctl status designhub-backend'"
|
||
echo " 查看后端日志: ssh ${SERVER_USER}@${SERVER_IP} 'tail -f ${APP_DIR}/logs/application.log'"
|
||
echo " 重启后端: ssh ${SERVER_USER}@${SERVER_IP} 'systemctl restart designhub-backend'"
|
||
echo " 兼容旧命令: ssh ${SERVER_USER}@${SERVER_IP} 'systemctl restart designhub' # designhub 为 designhub-backend 别名"
|
||
echo ""
|
||
echo "数据库信息:"
|
||
echo " 数据库名: ${DB_NAME}"
|
||
echo " 用户名: ${DB_USER}"
|
||
echo " 密码: ${DB_PASSWORD}"
|
||
echo ""
|
||
}
|
||
|
||
# 主执行流程
|
||
main() {
|
||
check_sshpass
|
||
test_connection
|
||
install_dependencies
|
||
create_directories
|
||
setup_mysql
|
||
setup_redis
|
||
upload_backend
|
||
upload_frontend
|
||
setup_backend
|
||
setup_frontend
|
||
setup_services
|
||
start_services
|
||
show_deployment_info
|
||
}
|
||
|
||
# 执行主函数
|
||
main
|