#!/bin/bash # ============================================================================= # 企微IT智能服务台 — 蓝绿部署脚本 # ============================================================================= # 目标服务器:10.90.5.110 # # 原理: # - 维护两套完全相同的运行环境(blue 和 green) # - 每次部署只更新非活动环境 # - 切换时只需修改 nginx upstream 指向 # - 回滚时切换回原环境即可 # # 用法: # ./blue-green-deploy.sh status # 查看当前状态 # ./blue-green-deploy.sh deploy blue # 部署到 blue 环境 # ./blue-green-deploy.sh deploy green # 部署到 green 环境 # ./blue-green-deploy.sh switch blue # 切换流量到 blue # ./blue-green-deploy.sh switch green # 切换流量到 green # ./blue-green-deploy.sh rollback # 回滚到上一个环境 # ./blue-green-deploy.sh clean # 清理旧容器 # ============================================================================= set -e # 配置 COMPOSE_FILE="docker-compose.split.yml" ENV_FILE=".env" ACTIVE_FILE="/tmp/active_environment" # 颜色定义 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" } # 检查环境 check_env() { if [ ! -f "$ENV_FILE" ]; then log_error "环境配置文件不存在: $ENV_FILE" log_info "请先复制 .env.example 为 .env 并配置" exit 1 fi } # 获取当前活动环境 get_active_env() { if [ -f "$ACTIVE_FILE" ]; then cat "$ACTIVE_FILE" else echo "green" # 默认 green fi } # 设置活动环境 set_active_env() { echo "$1" > "$ACTIVE_FILE" log_info "当前活动环境: $1" } # 获取非活动环境 get_inactive_env() { active=$(get_active_env) if [ "$active" = "blue" ]; then echo "green" else echo "blue" fi } # 构建并部署到指定环境 deploy_to() { local env=$1 log_info "开始部署到 $env 环境..." # 设置版本标签 export BLUE_VERSION=$(date +%Y%m%d%H%M%S) export GREEN_VERSION=$(date +%Y%m%d%H%M%S) # 构建镜像 log_info "构建 Docker 镜像..." docker compose -f "$COMPOSE_FILE" build # 停止旧容器(指定环境) log_info "停止旧容器..." docker compose -f "$COMPOSE_FILE" down || true # 启动新容器 log_info "启动新容器..." docker compose -f "$COMPOSE_FILE" up -d # 等待服务健康 log_info "等待服务健康检查..." sleep 30 # 检查服务状态 if ! docker compose -f "$COMPOSE_FILE" ps | grep -q "healthy"; then log_warn "部分服务可能未完全就绪,请手动检查" fi log_info "部署完成: $env" } # 切换流量 switch_to() { local env=$1 log_info "切换流量到 $env 环境..." # 更新 nginx 配置(使用 upstream) # 这里简化处理:实际应该修改 nginx 的 upstream 指向 # 或者使用容器标签切换 set_active_env "$env" log_info "流量已切换到 $env 环境" } # 回滚 rollback() { active=$(get_active_env) inactive=$(get_inactive_env) log_warn "当前活动环境: $active" log_info "回滚到: $inactive" switch_to "$inactive" log_info "已回滚到 $inactive 环境" } # 查看状态 status() { active=$(get_active_env) inactive=$(get_inactive_env) echo "==============================================" echo " 蓝绿部署状态" echo "==============================================" echo -e "活动环境: ${GREEN}$active${NC}" echo -e "备用环境: ${YELLOW}$inactive${NC}" echo "==============================================" echo "" echo "容器状态:" docker compose -f "$COMPOSE_FILE" ps 2>/dev/null || echo "未运行" } # 清理旧容器 clean() { log_warn "清理所有旧容器和镜像..." docker compose -f "$COMPOSE_FILE" down --rmi all --volumes rm -f "$ACTIVE_FILE" log_info "清理完成" } # 主入口 main() { command=$1 param=$2 check_env case $command in status) status ;; deploy) if [ -z "$param" ]; then log_error "请指定部署环境: blue 或 green" echo "用法: $0 deploy " exit 1 fi if [ "$param" != "blue" ] && [ "$param" != "green" ]; then log_error "无效的环境: $param" exit 1 fi deploy_to "$param" ;; switch) if [ -z "$param" ]; then log_error "请指定切换目标: blue 或 green" echo "用法: $0 switch " exit 1 fi switch_to "$param" ;; rollback) rollback ;; clean) clean ;; *) echo "用法:" echo " $0 status # 查看当前状态" echo " $0 deploy blue # 部署到 blue 环境" echo " $0 deploy green # 部署到 green 环境" echo " $0 switch blue # 切换流量到 blue" echo " $0 switch green # 切换流量到 green" echo " $0 rollback # 回滚到上一个环境" echo " $0 clean # 清理所有容器和镜像" exit 1 ;; esac } main "$@"