前后端目录重命名: - reading-platform-java/ → lesingle-edu-reading-platform-backend/ - reading-platform-frontend/ → lesingle-edu-reading-platform-frontend/ 更新相关文件: - 所有 shell 脚本中的目录引用 - pom.xml 和 application.yml 中的项目名称 - package.json 中的项目名称 - .claude/CLAUDE.md 中的路径引用 - README 文档中的路径引用
192 lines
4.8 KiB
Bash
192 lines
4.8 KiB
Bash
#!/bin/bash
|
||
|
||
#===============================================================================
|
||
# 后端生产环境部署脚本
|
||
#
|
||
# 使用方法:
|
||
# ./deploy-backend.sh user@host
|
||
# 或
|
||
# export REMOTE_USER=root
|
||
# export REMOTE_HOST=8.148.151.56
|
||
# ./deploy-backend.sh
|
||
#===============================================================================
|
||
|
||
set -e
|
||
|
||
# 配置
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
BACKEND_DIR="$SCRIPT_DIR/lesingle-edu-reading-platform-backend"
|
||
REMOTE_BASE_DIR="/www/wwwroot/reading-platform"
|
||
|
||
# SSH 配置
|
||
REMOTE_USER="${REMOTE_USER:-root}"
|
||
REMOTE_HOST="${REMOTE_HOST:-}"
|
||
REMOTE_PORT="${REMOTE_PORT:-22}"
|
||
|
||
# 颜色
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||
log_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
|
||
|
||
# 检查参数
|
||
if [ -n "$1" ]; then
|
||
if [[ "$1" == *"@"* ]]; then
|
||
REMOTE_USER=$(echo "$1" | cut -d'@' -f1)
|
||
REMOTE_HOST=$(echo "$1" | cut -d'@' -f2)
|
||
fi
|
||
fi
|
||
|
||
if [ -z "$REMOTE_HOST" ]; then
|
||
log_error "请提供远程主机:$0 user@host 或设置 REMOTE_HOST 环境变量"
|
||
exit 1
|
||
fi
|
||
|
||
echo ""
|
||
echo "=============================================="
|
||
echo " 后端部署到宝塔"
|
||
echo "=============================================="
|
||
echo ""
|
||
echo " 远程主机:$REMOTE_USER@$REMOTE_HOST"
|
||
echo " 部署目录:$REMOTE_BASE_DIR"
|
||
echo ""
|
||
|
||
# 步骤 1: 构建 JAR
|
||
log_step "构建后端..."
|
||
cd "$BACKEND_DIR"
|
||
|
||
if ! command -v mvn &> /dev/null; then
|
||
log_error "未找到 Maven"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查 Java 版本
|
||
java_ver=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d'.' -f1)
|
||
if [ "$java_ver" != "17" ]; then
|
||
log_warn "当前 Java 版本:$java_ver,建议使用 JDK 17"
|
||
fi
|
||
|
||
mvn clean package -DskipTests
|
||
|
||
JAR_FILE="$BACKEND_DIR/target/reading-platform-1.0.0.jar"
|
||
if [ ! -f "$JAR_FILE" ]; then
|
||
log_error "构建失败,未找到 JAR 包"
|
||
exit 1
|
||
fi
|
||
log_info "构建成功:$JAR_FILE"
|
||
|
||
# 步骤 2: 上传到服务器
|
||
log_step "上传到远程服务器..."
|
||
|
||
# 创建目录
|
||
ssh -o StrictHostKeyChecking=no -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" << 'ENDSSH'
|
||
mkdir -p /www/wwwroot/reading-platform
|
||
mkdir -p /www/wwwroot/reading-platform/logs
|
||
ENDSSH
|
||
|
||
# 上传 JAR
|
||
scp -o StrictHostKeyChecking=no -P "$REMOTE_PORT" \
|
||
"$JAR_FILE" \
|
||
"$REMOTE_USER@$REMOTE_HOST:$REMOTE_BASE_DIR/app.jar"
|
||
|
||
# 步骤 3: 创建启动脚本
|
||
log_step "创建启动脚本..."
|
||
|
||
cat > /tmp/baota-start.sh << 'EOF'
|
||
#!/bin/bash
|
||
APP_DIR="/www/wwwroot/reading-platform"
|
||
JAR_FILE="$APP_DIR/app.jar"
|
||
PID_FILE="$APP_DIR/app.pid"
|
||
LOG_FILE="$APP_DIR/logs/application.log"
|
||
|
||
# 环境变量
|
||
export SPRING_PROFILES_ACTIVE=prod
|
||
export SERVER_PORT=8480
|
||
|
||
# 停止旧进程
|
||
if [ -f "$PID_FILE" ]; then
|
||
OLD_PID=$(cat "$PID_FILE")
|
||
if kill -0 "$OLD_PID" 2>/dev/null; then
|
||
echo "停止旧进程 (PID: $OLD_PID)..."
|
||
kill "$OLD_PID"
|
||
sleep 3
|
||
fi
|
||
rm -f "$PID_FILE"
|
||
fi
|
||
pkill -f "app.jar" 2>/dev/null || true
|
||
|
||
# 启动
|
||
echo "启动应用..."
|
||
nohup java -jar \
|
||
-Xms512m \
|
||
-Xmx1024m \
|
||
-XX:+UseG1GC \
|
||
"$JAR_FILE" \
|
||
--spring.profiles.active=prod \
|
||
> "$LOG_FILE" 2>&1 &
|
||
|
||
NEW_PID=$!
|
||
echo $NEW_PID > "$PID_FILE"
|
||
echo "已启动 (PID: $NEW_PID)"
|
||
|
||
# 等待启动
|
||
for i in {1..30}; do
|
||
if curl -s http://localhost:8480/actuator/health 2>/dev/null; then
|
||
echo "启动成功!"
|
||
exit 0
|
||
fi
|
||
sleep 2
|
||
done
|
||
echo "启动超时,检查日志:tail -100 $LOG_FILE"
|
||
exit 1
|
||
EOF
|
||
|
||
scp -o StrictHostKeyChecking=no -P "$REMOTE_PORT" \
|
||
/tmp/baota-start.sh \
|
||
"$REMOTE_USER@$REMOTE_HOST:$REMOTE_BASE_DIR/start.sh"
|
||
|
||
# 步骤 4: 创建停止脚本
|
||
cat > /tmp/baota-stop.sh << 'EOF'
|
||
#!/bin/bash
|
||
PID_FILE="/www/wwwroot/reading-platform/app.pid"
|
||
if [ -f "$PID_FILE" ]; then
|
||
PID=$(cat "$PID_FILE")
|
||
if kill -0 "$PID" 2>/dev/null; then
|
||
kill "$PID"
|
||
echo "已停止 (PID: $PID)"
|
||
fi
|
||
rm -f "$PID_FILE"
|
||
fi
|
||
pkill -f "app.jar" 2>/dev/null || true
|
||
echo "已停止"
|
||
EOF
|
||
|
||
scp -o StrictHostKeyChecking=no -P "$REMOTE_PORT" \
|
||
/tmp/baota-stop.sh \
|
||
"$REMOTE_USER@$REMOTE_HOST:$REMOTE_BASE_DIR/stop.sh"
|
||
|
||
# 设置权限
|
||
ssh -o StrictHostKeyChecking=no -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" \
|
||
"chmod +x $REMOTE_BASE_DIR/start.sh $REMOTE_BASE_DIR/stop.sh"
|
||
|
||
log_info "部署完成"
|
||
|
||
echo ""
|
||
echo "=============================================="
|
||
echo " 后端部署完成!"
|
||
echo "=============================================="
|
||
echo ""
|
||
echo " 远程登录:ssh $REMOTE_USER@$REMOTE_HOST"
|
||
echo " 启动服务:cd $REMOTE_BASE_DIR && ./start.sh"
|
||
echo " 停止服务:cd $REMOTE_BASE_DIR && ./stop.sh"
|
||
echo " 查看日志:tail -f $REMOTE_BASE_DIR/logs/application.log"
|
||
echo ""
|
||
echo " 健康检查:curl http://localhost:8480/actuator/health"
|
||
echo ""
|