#!/bin/bash # 环境管理脚本 - 用于切换不同环境的Docker Compose配置 # Requirements: 5.3, 6.5 set -e # 脚本目录 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOCKER_DIR="$(dirname "$SCRIPT_DIR")" PROJECT_ROOT="$(dirname "$DOCKER_DIR")" # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 日志函数 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_debug() { echo -e "${BLUE}[DEBUG]${NC} $1" } # 显示帮助信息 show_help() { cat << EOF 环境管理脚本 - 若依框架Docker部署 用法: $0 [命令] [环境] 命令: deploy 部署指定环境 stop 停止指定环境 restart 重启指定环境 status 查看指定环境状态 logs 查看指定环境日志 clean 清理指定环境 backup 备份指定环境数据 list 列出所有可用环境 help 显示此帮助信息 环境: development (dev) 开发环境 staging (stage) 测试环境 production (prod) 生产环境 示例: $0 deploy development # 部署开发环境 $0 stop prod # 停止生产环境 $0 logs staging # 查看测试环境日志 $0 status dev # 查看开发环境状态 EOF } # 验证环境参数 validate_environment() { local env=$1 case $env in development|dev) echo "development" ;; staging|stage) echo "staging" ;; production|prod) echo "production" ;; *) log_error "无效的环境: $env" log_info "支持的环境: development, staging, production" exit 1 ;; esac } # 获取compose文件路径 get_compose_file() { local env=$1 echo "${DOCKER_DIR}/docker-compose.${env}.yml" } # 获取环境配置文件路径 get_env_file() { local env=$1 echo "${DOCKER_DIR}/environments/.env.${env}" } # 检查文件是否存在 check_files() { local env=$1 local compose_file=$(get_compose_file $env) local env_file=$(get_env_file $env) if [ ! -f "$compose_file" ]; then log_error "Compose文件不存在: $compose_file" exit 1 fi if [ ! -f "$env_file" ]; then log_error "环境配置文件不存在: $env_file" exit 1 fi log_debug "文件检查通过: $compose_file, $env_file" } # 部署环境 deploy_environment() { local env=$1 local compose_file=$(get_compose_file $env) local env_file=$(get_env_file $env) log_info "开始部署 $env 环境..." # 检查文件 check_files $env # 创建必要的目录 log_info "创建数据目录..." source "$env_file" mkdir -p "${MYSQL_DATA_PATH:-./data/$env/mysql}" mkdir -p "${MYSQL_LOG_PATH:-./data/$env/mysql-logs}" mkdir -p "${BACKEND_LOG_PATH:-./data/$env/backend-logs}" mkdir -p "${BACKEND_UPLOAD_PATH:-./data/$env/uploads}" mkdir -p "${FRONTEND_LOG_PATH:-./data/$env/nginx-logs}" if [ "$env" != "development" ]; then mkdir -p "${BACKUP_DATA_PATH:-./data/$env/backups}" fi # 部署服务 log_info "启动Docker Compose服务..." cd "$DOCKER_DIR" docker-compose -f "$compose_file" --env-file "$env_file" up -d # 等待服务启动 log_info "等待服务启动..." sleep 10 # 检查服务状态 check_services $env log_info "$env 环境部署完成!" } # 停止环境 stop_environment() { local env=$1 local compose_file=$(get_compose_file $env) local env_file=$(get_env_file $env) log_info "停止 $env 环境..." cd "$DOCKER_DIR" docker-compose -f "$compose_file" --env-file "$env_file" down log_info "$env 环境已停止" } # 重启环境 restart_environment() { local env=$1 log_info "重启 $env 环境..." stop_environment $env sleep 5 deploy_environment $env } # 查看环境状态 check_services() { local env=$1 local compose_file=$(get_compose_file $env) local env_file=$(get_env_file $env) log_info "检查 $env 环境服务状态..." cd "$DOCKER_DIR" docker-compose -f "$compose_file" --env-file "$env_file" ps # 健康检查 log_info "执行健康检查..." local services=("anxin-mysql-${env}" "anxin-backend-${env}" "anxin-frontend-${env}") for service in "${services[@]}"; do if docker ps --format "table {{.Names}}" | grep -q "$service"; then local health=$(docker inspect --format='{{.State.Health.Status}}' "$service" 2>/dev/null || echo "no-healthcheck") if [ "$health" = "healthy" ] || [ "$health" = "no-healthcheck" ]; then log_info "✓ $service: 运行正常" else log_warn "⚠ $service: 健康检查失败 ($health)" fi else log_error "✗ $service: 未运行" fi done } # 查看日志 view_logs() { local env=$1 local service=$2 local compose_file=$(get_compose_file $env) local env_file=$(get_env_file $env) cd "$DOCKER_DIR" if [ -n "$service" ]; then log_info "查看 $env 环境 $service 服务日志..." docker-compose -f "$compose_file" --env-file "$env_file" logs -f "$service" else log_info "查看 $env 环境所有服务日志..." docker-compose -f "$compose_file" --env-file "$env_file" logs -f fi } # 清理环境 clean_environment() { local env=$1 local compose_file=$(get_compose_file $env) local env_file=$(get_env_file $env) log_warn "即将清理 $env 环境 (包括数据卷)..." read -p "确认继续? (y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then log_info "清理 $env 环境..." cd "$DOCKER_DIR" docker-compose -f "$compose_file" --env-file "$env_file" down -v --remove-orphans docker system prune -f log_info "$env 环境清理完成" else log_info "取消清理操作" fi } # 备份环境数据 backup_environment() { local env=$1 log_info "备份 $env 环境数据..." case $env in production) docker exec anxin-mysql-prod /backup.sh ;; staging) docker exec anxin-mysql-staging /backup.sh ;; development) log_warn "开发环境通常不需要备份" ;; esac log_info "$env 环境数据备份完成" } # 列出所有环境 list_environments() { log_info "可用环境:" echo " development (dev) - 开发环境" echo " staging (stage) - 测试环境" echo " production (prod) - 生产环境" echo log_info "当前运行的容器:" docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep anxin || echo " 无运行中的容器" } # 主函数 main() { local command=$1 local environment=$2 case $command in deploy) if [ -z "$environment" ]; then log_error "请指定环境" show_help exit 1 fi env=$(validate_environment "$environment") deploy_environment "$env" ;; stop) if [ -z "$environment" ]; then log_error "请指定环境" show_help exit 1 fi env=$(validate_environment "$environment") stop_environment "$env" ;; restart) if [ -z "$environment" ]; then log_error "请指定环境" show_help exit 1 fi env=$(validate_environment "$environment") restart_environment "$env" ;; status) if [ -z "$environment" ]; then log_error "请指定环境" show_help exit 1 fi env=$(validate_environment "$environment") check_services "$env" ;; logs) if [ -z "$environment" ]; then log_error "请指定环境" show_help exit 1 fi env=$(validate_environment "$environment") view_logs "$env" "$3" ;; clean) if [ -z "$environment" ]; then log_error "请指定环境" show_help exit 1 fi env=$(validate_environment "$environment") clean_environment "$env" ;; backup) if [ -z "$environment" ]; then log_error "请指定环境" show_help exit 1 fi env=$(validate_environment "$environment") backup_environment "$env" ;; list) list_environments ;; help|--help|-h) show_help ;; *) log_error "未知命令: $command" show_help exit 1 ;; esac } # 检查Docker是否安装 if ! command -v docker &> /dev/null; then log_error "Docker未安装或不在PATH中" exit 1 fi if ! command -v docker-compose &> /dev/null; then log_error "Docker Compose未安装或不在PATH中" exit 1 fi # 执行主函数 main "$@"