#!/bin/bash # QAUP 环境验证脚本 set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" ENV_FILE="$PROJECT_ROOT/.env" # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' print_message() { local color=$1 local message=$2 echo -e "${color}${message}${NC}" } # 检查系统要求 check_system_requirements() { print_message $BLUE "检查系统要求..." local errors=0 # 检查操作系统 if [[ "$OSTYPE" == "linux-gnu"* ]]; then print_message $GREEN "✓ 操作系统: Linux" else print_message $YELLOW "⚠ 操作系统: $OSTYPE (建议使用 Linux)" fi # 检查 Docker if command -v docker &> /dev/null; then local docker_version=$(docker --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) print_message $GREEN "✓ Docker: $docker_version" # 检查 Docker 版本 local major_version=$(echo $docker_version | cut -d. -f1) local minor_version=$(echo $docker_version | cut -d. -f2) if [ $major_version -lt 20 ] || ([ $major_version -eq 20 ] && [ $minor_version -lt 10 ]); then print_message $YELLOW "⚠ Docker 版本较低,建议升级到 20.10+" fi else print_message $RED "✗ Docker 未安装" errors=$((errors + 1)) fi # 检查 Docker Compose if command -v docker-compose &> /dev/null; then local compose_version=$(docker-compose --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) print_message $GREEN "✓ Docker Compose: $compose_version" else print_message $RED "✗ Docker Compose 未安装" errors=$((errors + 1)) fi # 检查内存 local total_mem=$(free -m | awk 'NR==2{printf "%.0f", $2/1024}') if [ $total_mem -ge 4 ]; then print_message $GREEN "✓ 内存: ${total_mem}GB" else print_message $YELLOW "⚠ 内存: ${total_mem}GB (建议至少 4GB)" fi # 检查磁盘空间 local available_space=$(df -BG . | awk 'NR==2 {print $4}' | sed 's/G//') if [ $available_space -ge 20 ]; then print_message $GREEN "✓ 可用磁盘空间: ${available_space}GB" else print_message $YELLOW "⚠ 可用磁盘空间: ${available_space}GB (建议至少 20GB)" fi return $errors } # 检查端口占用 check_ports() { print_message $BLUE "检查端口占用..." local ports=(80 443 8080 5432 6379) local occupied_ports=() for port in "${ports[@]}"; do if netstat -tuln 2>/dev/null | grep -q ":$port "; then occupied_ports+=($port) print_message $YELLOW "⚠ 端口 $port 已被占用" else print_message $GREEN "✓ 端口 $port 可用" fi done if [ ${#occupied_ports[@]} -gt 0 ]; then print_message $YELLOW "警告: 以下端口被占用: ${occupied_ports[*]}" print_message $YELLOW "请在 .env 文件中修改端口配置或停止占用端口的服务" return 1 fi return 0 } # 检查 Docker 服务状态 check_docker_service() { print_message $BLUE "检查 Docker 服务状态..." if systemctl is-active --quiet docker; then print_message $GREEN "✓ Docker 服务正在运行" else print_message $RED "✗ Docker 服务未运行" print_message $YELLOW "请运行: sudo systemctl start docker" return 1 fi # 检查当前用户是否在 docker 组中 if groups | grep -q docker; then print_message $GREEN "✓ 当前用户在 docker 组中" else print_message $YELLOW "⚠ 当前用户不在 docker 组中" print_message $YELLOW "请运行: sudo usermod -aG docker $USER" print_message $YELLOW "然后重新登录或运行: newgrp docker" fi return 0 } # 检查环境配置 check_environment_config() { print_message $BLUE "检查环境配置..." local errors=0 # 检查环境文件 if [ ! -f "$ENV_FILE" ]; then print_message $RED "✗ 环境文件不存在: $ENV_FILE" print_message $YELLOW "请运行: docker/config-manager.sh init" return 1 fi source "$ENV_FILE" # 检查必需的环境变量 local required_vars=( "POSTGRES_DB" "POSTGRES_USER" "POSTGRES_PASSWORD" "APP_DB_USER" "APP_DB_PASSWORD" ) for var in "${required_vars[@]}"; do if [ -z "${!var}" ]; then print_message $RED "✗ 必需的环境变量未设置: $var" errors=$((errors + 1)) else print_message $GREEN "✓ $var 已设置" fi done # 检查密码强度 if [ ${#POSTGRES_PASSWORD} -lt 8 ]; then print_message $YELLOW "⚠ PostgreSQL 密码长度少于8位" errors=$((errors + 1)) fi if [ ${#APP_DB_PASSWORD} -lt 8 ]; then print_message $YELLOW "⚠ 应用数据库密码长度少于8位" errors=$((errors + 1)) fi return $errors } # 检查文件权限 check_file_permissions() { print_message $BLUE "检查文件权限..." local errors=0 # 检查脚本文件权限 local script_files=( "docker/start.sh" "docker/build-frontend.sh" "docker/nginx/start-nginx.sh" "docker/postgres/init-db.sh" "docker/postgres/db-manager.sh" "docker/prepare-offline-images.sh" "docker/load-images.sh" "docker/docker-compose-manager.sh" "docker/config-manager.sh" "docker/secrets-manager.sh" ) for script in "${script_files[@]}"; do local script_path="$PROJECT_ROOT/$script" if [ -f "$script_path" ]; then if [ -x "$script_path" ]; then print_message $GREEN "✓ $script 可执行" else print_message $YELLOW "⚠ $script 不可执行" chmod +x "$script_path" print_message $GREEN "✓ 已修复 $script 权限" fi else print_message $RED "✗ 脚本文件不存在: $script" errors=$((errors + 1)) fi done return $errors } # 检查目录结构 check_directory_structure() { print_message $BLUE "检查目录结构..." local required_dirs=( "docker" "docker/nginx" "docker/postgres" "config" ) local errors=0 for dir in "${required_dirs[@]}"; do local dir_path="$PROJECT_ROOT/$dir" if [ -d "$dir_path" ]; then print_message $GREEN "✓ 目录存在: $dir" else print_message $RED "✗ 目录不存在: $dir" errors=$((errors + 1)) fi done return $errors } # 检查 Docker 镜像 check_docker_images() { print_message $BLUE "检查 Docker 镜像..." # 从 image-versions.env 文件中读取镜像配置 local image_versions_file="$SCRIPT_DIR/image-versions.env" if [ -f "$image_versions_file" ]; then source "$image_versions_file" else print_message $RED "✗ 镜像版本配置文件不存在: $image_versions_file" return 1 fi # 使用配置文件中定义的镜像名称 local base_images=( "$POSTGRES_IMAGE" "$REDIS_IMAGE" "$QAUP_APP_IMAGE" "$QAUP_NGINX_IMAGE" ) local missing_images=() for image in "${base_images[@]}"; do if docker image inspect "$image" &> /dev/null; then print_message $GREEN "✓ 镜像存在: $image" else missing_images+=("$image") print_message $YELLOW "⚠ 镜像不存在: $image" fi done if [ ${#missing_images[@]} -gt 0 ]; then print_message $YELLOW "缺失的镜像: ${missing_images[*]}" print_message $YELLOW "请运行: ./docker/prepare-offline-images.sh 或手动拉取镜像" return 1 fi return 0 } # 生成验证报告 generate_report() { local total_errors=$1 print_message $BLUE "=========================================" print_message $BLUE "环境验证报告" print_message $BLUE "=========================================" if [ $total_errors -eq 0 ]; then print_message $GREEN "✓ 环境验证通过,可以开始部署" print_message $GREEN "建议的下一步操作:" echo " 1. 运行: docker/docker-compose-manager.sh prod build" echo " 2. 运行: docker/docker-compose-manager.sh prod start" else print_message $RED "✗ 环境验证失败,发现 $total_errors 个问题" print_message $YELLOW "请修复上述问题后重新运行验证" fi print_message $BLUE "=========================================" } # 主函数 main() { print_message $GREEN "开始 QAUP 环境验证..." print_message $BLUE "=========================================" local total_errors=0 # 执行各项检查 check_system_requirements total_errors=$((total_errors + $?)) echo "" check_docker_service total_errors=$((total_errors + $?)) echo "" check_ports total_errors=$((total_errors + $?)) echo "" check_directory_structure total_errors=$((total_errors + $?)) echo "" check_file_permissions total_errors=$((total_errors + $?)) echo "" check_environment_config total_errors=$((total_errors + $?)) echo "" check_docker_images total_errors=$((total_errors + $?)) echo "" generate_report $total_errors exit $total_errors } main "$@"