#!/bin/bash # 前端服务诊断脚本 # 用于诊断前端服务启动问题 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # 检查前端容器状态 check_frontend_container() { log_info "检查前端容器状态..." # 检查容器是否存在 if docker ps -a --filter "name=anxin-frontend-prod" --format "{{.Names}}" | grep -q "anxin-frontend-prod"; then log_success "✓ 前端容器存在" # 显示容器状态 echo "容器状态:" docker ps -a --filter "name=anxin-frontend-prod" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" # 检查容器是否正在运行 if docker ps --filter "name=anxin-frontend-prod" --format "{{.Names}}" | grep -q "anxin-frontend-prod"; then log_success "✓ 前端容器正在运行" else log_error "✗ 前端容器已停止" # 显示退出代码 local exit_code=$(docker inspect anxin-frontend-prod --format='{{.State.ExitCode}}' 2>/dev/null || echo "unknown") log_info "退出代码: $exit_code" fi else log_error "✗ 前端容器不存在" return 1 fi } # 检查前端镜像 check_frontend_image() { log_info "检查前端镜像..." if docker images --filter "reference=anxin-frontend:prod" --format "{{.Repository}}:{{.Tag}}" | grep -q "anxin-frontend:prod"; then log_success "✓ 前端镜像存在" # 显示镜像信息 echo "镜像信息:" docker images --filter "reference=anxin-frontend:prod" --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}" else log_error "✗ 前端镜像不存在" log_info "需要构建前端镜像" fi } # 检查前端依赖服务 check_frontend_dependencies() { log_info "检查前端依赖服务..." # 检查后端服务 if docker ps --filter "name=anxin-backend-prod" --format "{{.Names}}" | grep -q "anxin-backend-prod"; then log_success "✓ 后端服务正在运行" # 检查后端健康状态 local backend_health=$(docker inspect anxin-backend-prod --format='{{.State.Health.Status}}' 2>/dev/null || echo "unknown") log_info "后端健康状态: $backend_health" else log_error "✗ 后端服务未运行" fi } # 检查前端日志 check_frontend_logs() { log_info "检查前端启动日志..." if docker ps -a --filter "name=anxin-frontend-prod" --format "{{.Names}}" | grep -q "anxin-frontend-prod"; then echo "最近的前端日志:" echo "----------------------------------------" docker logs anxin-frontend-prod --tail 50 2>&1 || echo "无法获取日志" echo "----------------------------------------" else log_warn "前端容器不存在,无法查看日志" fi } # 检查前端配置 check_frontend_config() { log_info "检查前端配置..." # 检查docker-compose配置 if [[ -f "docker-compose.production.yml" ]]; then log_success "✓ 找到docker-compose配置文件" # 显示前端服务配置 echo "前端服务配置:" echo "----------------------------------------" sed -n '/anxin-frontend:/,/^ [a-zA-Z]/p' docker-compose.production.yml | head -20 echo "----------------------------------------" else log_error "✗ 未找到docker-compose配置文件" fi # 检查nginx配置 if [[ -f "configs/nginx.conf.prod" ]]; then log_success "✓ 找到nginx生产环境配置" else log_warn "未找到nginx生产环境配置文件" fi } # 检查端口占用 check_port_usage() { log_info "检查端口占用情况..." if [[ -f "environments/.env.production" ]]; then source environments/.env.production local frontend_port=${FRONTEND_PORT:-80} local ssl_port=${FRONTEND_SSL_PORT:-443} # 检查HTTP端口 log_info "检查端口 $frontend_port..." if netstat -tlnp 2>/dev/null | grep ":$frontend_port " || ss -tlnp 2>/dev/null | grep ":$frontend_port "; then log_success "✓ 端口 $frontend_port 正在使用" else log_warn "端口 $frontend_port 未被使用" fi # 检查HTTPS端口 if [[ "$ssl_port" != "443" ]] || [[ "$frontend_port" != "80" ]]; then log_info "检查端口 $ssl_port..." if netstat -tlnp 2>/dev/null | grep ":$ssl_port " || ss -tlnp 2>/dev/null | grep ":$ssl_port "; then log_success "✓ 端口 $ssl_port 正在使用" else log_warn "端口 $ssl_port 未被使用" fi fi fi } # 检查前端文件 check_frontend_files() { log_info "检查前端相关文件..." # 检查Dockerfile if [[ -f "frontend/Dockerfile" ]]; then log_success "✓ 找到前端Dockerfile" else log_error "✗ 未找到前端Dockerfile" fi # 检查前端源码目录 if [[ -d "../RuoYi-Vue3" ]]; then log_success "✓ 找到前端源码目录" else log_error "✗ 未找到前端源码目录" fi } # 尝试手动启动前端服务 manual_start_frontend() { log_info "尝试手动启动前端服务..." # 停止现有容器 docker stop anxin-frontend-prod 2>/dev/null || true docker rm anxin-frontend-prod 2>/dev/null || true # 尝试启动前端服务 log_info "启动前端服务..." if ./deploy.sh start frontend -e production; then log_success "✓ 前端服务启动命令执行成功" # 等待启动 sleep 10 # 检查启动结果 if docker ps --filter "name=anxin-frontend-prod" --format "{{.Names}}" | grep -q "anxin-frontend-prod"; then log_success "✓ 前端服务启动成功" else log_error "✗ 前端服务启动失败" fi else log_error "✗ 前端服务启动命令失败" fi } # 显示修复建议 show_fix_suggestions() { log_info "修复建议:" echo "========================================" echo "根据诊断结果,可能的解决方案:" echo "" echo "1. 如果前端镜像不存在:" echo " ./build.sh build -c frontend -e production" echo "" echo "2. 如果容器启动失败:" echo " ./deploy.sh logs frontend -e production" echo " 检查具体错误信息" echo "" echo "3. 如果依赖服务未就绪:" echo " ./deploy.sh restart backend -e production" echo " 等待后端服务完全启动后再启动前端" echo "" echo "4. 如果端口冲突:" echo " 检查environments/.env.production中的端口配置" echo " 确保端口未被其他服务占用" echo "" echo "5. 如果配置文件缺失:" echo " 检查configs/nginx.conf.prod是否存在" echo " 检查frontend/Dockerfile是否存在" echo "" echo "6. 完全重新部署:" echo " ./deploy.sh down -e production" echo " ./deploy.sh up -e production" echo "========================================" } # 主函数 main() { local action=${1:-"diagnose"} log_info "前端服务诊断工具" echo "========================================" case $action in "diagnose") check_frontend_container echo "" check_frontend_image echo "" check_frontend_dependencies echo "" check_frontend_config echo "" check_port_usage echo "" check_frontend_files echo "" check_frontend_logs echo "" show_fix_suggestions ;; "start") manual_start_frontend ;; "logs") check_frontend_logs ;; *) echo "用法: $0 [diagnose|start|logs]" echo " diagnose - 诊断前端服务问题(默认)" echo " start - 尝试手动启动前端服务" echo " logs - 查看前端服务日志" exit 1 ;; esac echo "========================================" log_success "操作完成!" } # 如果脚本被直接执行 if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi