Files

218 lines
5.5 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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 <blue|green>"
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 <blue|green>"
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 "$@"