262 lines
8.7 KiB
Bash
262 lines
8.7 KiB
Bash
#!/bin/bash
|
||
|
||
# QAUP 一键部署脚本
|
||
|
||
set -e
|
||
|
||
# 颜色输出
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
BLUE='\033[0;34m'
|
||
YELLOW='\033[1;33m'
|
||
NC='\033[0m'
|
||
|
||
print_message() {
|
||
echo -e "${1}${2}${NC}"
|
||
}
|
||
|
||
print_message $BLUE "=== QAUP 一键部署 ==="
|
||
|
||
# 环境检查
|
||
print_message $BLUE "1. 检查部署环境..."
|
||
|
||
# 检查操作系统
|
||
if [[ "$OSTYPE" != "linux-gnu"* ]]; then
|
||
print_message $YELLOW "⚠️ 建议在Linux环境中运行"
|
||
fi
|
||
|
||
# 检查必要文件
|
||
REQUIRED_FILES=("app.jar" "docker-compose.yml" "config.yml" "images.tar.gz")
|
||
for file in "${REQUIRED_FILES[@]}"; do
|
||
if [ ! -f "$file" ]; then
|
||
print_message $RED "❌ 缺失必要文件: $file"
|
||
print_message $BLUE "请确保所有文件都存在,或重新解压部署包"
|
||
exit 1
|
||
fi
|
||
done
|
||
print_message $GREEN "✓ 所有必要文件检查通过"
|
||
|
||
# 检查Docker
|
||
if ! command -v docker &> /dev/null; then
|
||
print_message $RED "❌ Docker 未安装"
|
||
print_message $BLUE "请安装 Docker: sudo apt install docker.io"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查Docker服务
|
||
if ! sudo systemctl is-active --quiet docker; then
|
||
print_message $YELLOW "⚠️ Docker 服务未启动,正在启动..."
|
||
sudo systemctl start docker
|
||
sleep 5
|
||
fi
|
||
|
||
DOCKER_VERSION=$(docker --version)
|
||
print_message $GREEN "✓ Docker 版本: $DOCKER_VERSION"
|
||
|
||
# 检查Docker Compose
|
||
if ! docker compose version &> /dev/null && ! docker-compose version &> /dev/null; then
|
||
print_message $RED "❌ Docker Compose 未安装"
|
||
print_message $BLUE "请安装 Docker Compose: sudo apt install docker-compose"
|
||
exit 1
|
||
fi
|
||
print_message $GREEN "✓ Docker Compose 检查通过"
|
||
|
||
# 检查磁盘空间(至少需要3GB)
|
||
AVAILABLE_SPACE=$(df . | tail -1 | awk '{print $4}')
|
||
REQUIRED_SPACE=$((3 * 1024 * 1024)) # 3GB in KB
|
||
if [ "$AVAILABLE_SPACE" -lt "$REQUIRED_SPACE" ]; then
|
||
print_message $RED "❌ 磁盘空间不足"
|
||
print_message $BLUE "可用空间: $(($AVAILABLE_SPACE / 1024 / 1024))GB, 需要: 3GB"
|
||
exit 1
|
||
fi
|
||
print_message $GREEN "✓ 磁盘空间充足: $(($AVAILABLE_SPACE / 1024 / 1024))GB"
|
||
|
||
# 检查端口占用
|
||
PORTS=(8080 5432 6379)
|
||
print_message $BLUE "2. 检查端口占用..."
|
||
for port in "${PORTS[@]}"; do
|
||
if netstat -tuln 2>/dev/null | grep -q ":$port " || ss -tuln 2>/dev/null | grep -q ":$port "; then
|
||
print_message $YELLOW "⚠️ 端口 $port 已被占用"
|
||
print_message $BLUE "请停止占用该端口的服务或修改端口配置"
|
||
fi
|
||
done
|
||
print_message $GREEN "✓ 端口检查完成"
|
||
|
||
# 检查Docker镜像
|
||
print_message $BLUE "3. 检查Docker镜像..."
|
||
if [ -f "images.tar.gz" ]; then
|
||
print_message $BLUE "载入预构建镜像..."
|
||
if ! docker load -i images.tar.gz; then
|
||
print_message $RED "❌ 镜像载入失败"
|
||
exit 1
|
||
fi
|
||
print_message $GREEN "✓ 镜像载入成功"
|
||
else
|
||
print_message $YELLOW "⚠️ 未找到镜像包,将尝试在线拉取"
|
||
|
||
# 尝试拉取镜像
|
||
IMAGES=("m.daocloud.io/docker.io/postgis/postgis:17-3.5-alpine" \
|
||
"m.daocloud.io/docker.io/library/redis:8.0-alpine" \
|
||
"m.daocloud.io/docker.io/library/eclipse-temurin:21-jre")
|
||
|
||
for image in "${IMAGES[@]}"; do
|
||
if ! docker pull --platform linux/amd64 "$image"; then
|
||
print_message $RED "❌ 镜像拉取失败: $image"
|
||
exit 1
|
||
fi
|
||
done
|
||
print_message $GREEN "✓ 所有镜像拉取成功"
|
||
fi
|
||
|
||
# 停止可能存在的冲突容器
|
||
print_message $BLUE "4. 清理冲突容器..."
|
||
docker compose down 2>/dev/null || true
|
||
docker rm -f $(docker ps -aq --filter name=qaup) 2>/dev/null || true
|
||
print_message $GREEN "✓ 冲突容器清理完成"
|
||
|
||
# 创建数据目录
|
||
print_message $BLUE "5. 创建数据目录..."
|
||
mkdir -p data/postgres data/redis logs backup
|
||
|
||
# 设置目录权限
|
||
chmod 755 data logs backup
|
||
chmod 700 data/postgres data/redis
|
||
print_message $GREEN "✓ 数据目录创建完成"
|
||
|
||
# 验证配置文件
|
||
print_message $BLUE "6. 验证配置文件..."
|
||
|
||
# 检查docker-compose.yml语法
|
||
if ! docker compose config -q; then
|
||
print_message $RED "❌ docker-compose.yml 配置语法错误"
|
||
exit 1
|
||
fi
|
||
print_message $GREEN "✓ docker-compose.yml 语法正确"
|
||
|
||
# 检查应用配置文件
|
||
if ! grep -q "qaup:" config.yml; then
|
||
print_message $RED "❌ config.yml 配置不完整"
|
||
exit 1
|
||
fi
|
||
print_message $GREEN "✓ 应用配置文件正常"
|
||
|
||
# 启动基础设施服务
|
||
print_message $BLUE "7. 启动基础设施服务..."
|
||
docker compose up -d qaup-postgres qaup-redis
|
||
|
||
# 等待数据库启动
|
||
print_message $BLUE "等待数据库启动(30秒)..."
|
||
sleep 30
|
||
|
||
# 检查数据库状态
|
||
if docker exec qaup-postgres pg_isready -U qaup > /dev/null 2>&1; then
|
||
print_message $GREEN "✓ PostgreSQL 数据库启动成功"
|
||
else
|
||
print_message $RED "❌ PostgreSQL 启动失败"
|
||
print_message $BLUE "数据库日志:"
|
||
docker compose logs qaup-postgres
|
||
exit 1
|
||
fi
|
||
|
||
# 检查Redis状态
|
||
if docker exec qaup-redis redis-cli ping > /dev/null 2>&1; then
|
||
print_message $GREEN "✓ Redis 缓存服务启动成功"
|
||
else
|
||
print_message $RED "❌ Redis 启动失败"
|
||
print_message $BLUE "Redis日志:"
|
||
docker compose logs qaup-redis
|
||
exit 1
|
||
fi
|
||
|
||
# 启动应用服务
|
||
print_message $BLUE "8. 启动应用服务..."
|
||
docker compose up -d qaup-app
|
||
|
||
# 等待应用启动和数据库迁移
|
||
print_message $BLUE "9. 等待应用启动和数据库迁移..."
|
||
print_message $BLUE " 这可能需要2-3分钟,请耐心等待..."
|
||
|
||
WAIT_TIME=0
|
||
HEALTH_URL="http://localhost:8080/actuator/health"
|
||
|
||
while [ $WAIT_TIME -lt 180 ]; do
|
||
sleep 10
|
||
WAIT_TIME=$((WAIT_TIME + 10))
|
||
|
||
# 检查应用健康状态
|
||
if curl -f -s "$HEALTH_URL" > /dev/null 2>&1; then
|
||
print_message $GREEN "✓ 应用启动成功!"
|
||
break
|
||
fi
|
||
|
||
# 显示等待进度
|
||
if [ $((WAIT_TIME % 30)) -eq 0 ]; then
|
||
print_message $BLUE " 已等待 ${WAIT_TIME} 秒..."
|
||
|
||
# 检查是否有迁移相关的日志
|
||
MIGRATION_LOGS=$(docker compose logs qaup-app 2>/dev/null | grep -i "flyway\|migration" | tail -3)
|
||
if [ -n "$MIGRATION_LOGS" ]; then
|
||
print_message $BLUE " 迁移进度:"
|
||
echo "$MIGRATION_LOGS" | while read line; do
|
||
print_message $BLUE " $line"
|
||
done
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# 最终验证
|
||
print_message $BLUE "10. 最终验证..."
|
||
|
||
if curl -f -s "$HEALTH_URL" > /dev/null 2>&1; then
|
||
# 获取服务状态
|
||
APP_STATUS=$(docker compose ps qaup-app --format json | jq -r '.[0].State' 2>/dev/null || echo "unknown")
|
||
DB_STATUS=$(docker compose ps qaup-postgres --format json | jq -r '.[0].State' 2>/dev/null || echo "unknown")
|
||
REDIS_STATUS=$(docker compose ps qaup-redis --format json | jq -r '.[0].State' 2>/dev/null || echo "unknown")
|
||
|
||
print_message $GREEN "🎉 部署成功完成!"
|
||
echo ""
|
||
print_message $GREEN "📊 服务状态:"
|
||
print_message $BLUE " 应用服务: $APP_STATUS"
|
||
print_message $BLUE " 数据库: $DB_STATUS"
|
||
print_message $BLUE " 缓存服务: $REDIS_STATUS"
|
||
echo ""
|
||
print_message $BLUE "🌐 访问信息:"
|
||
print_message $BLUE " Web管理: http://localhost:8080"
|
||
print_message $BLUE " 健康检查: $HEALTH_URL"
|
||
print_message $BLUE " 数据库: localhost:5432 (qaup/qaup123)"
|
||
print_message $BLUE " Redis: localhost:6379"
|
||
echo ""
|
||
print_message $BLUE "👤 初始登录:"
|
||
print_message $BLUE " 用户名: admin"
|
||
print_message $BLUE " 密码: admin123"
|
||
echo ""
|
||
print_message $BLUE "📋 管理命令:"
|
||
print_message $BLUE " 查看状态: docker compose ps"
|
||
print_message $BLUE " 查看日志: docker compose logs -f qaup-app"
|
||
print_message $BLUE " 查看迁移: docker exec qaup-postgres psql -U qaup -d qaup -c \"SELECT version,description FROM flyway_schema_history ORDER BY installed_rank DESC LIMIT 5;\""
|
||
print_message $BLUE " 停止服务: docker compose down"
|
||
print_message $BLUE " 重启应用: docker compose restart qaup-app"
|
||
print_message $BLUE " 升级应用: ./deploy-update.sh"
|
||
echo ""
|
||
print_message $GREEN "🚀 QAUP 系统已就绪!"
|
||
|
||
else
|
||
print_message $RED "❌ 应用启动失败"
|
||
print_message $BLUE "请检查以下信息:"
|
||
echo ""
|
||
print_message $BLUE "📋 应用日志:"
|
||
docker compose logs --tail=50 qaup-app
|
||
echo ""
|
||
print_message $BLUE "📋 数据库日志:"
|
||
docker compose logs --tail=20 qaup-postgres
|
||
echo ""
|
||
print_message $BLUE "📋 容器状态:"
|
||
docker compose ps
|
||
echo ""
|
||
print_message $YELLOW "💡 可能的解决方案:"
|
||
print_message $BLUE "1. 检查端口是否被占用: netstat -tuln | grep ':8080'"
|
||
print_message $BLUE "2. 检查磁盘空间: df -h"
|
||
print_message $BLUE "3. 重启Docker服务: sudo systemctl restart docker"
|
||
print_message $BLUE "4. 清理Docker资源: docker system prune -a"
|
||
exit 1
|
||
fi |