下面提供一个支持多环境、Docker 集成、蓝绿部署的完整方案。包含一个核心部署脚本、示例配置文件和 Docker Compose 配置,适用于微服务或 Web 应用。该方案实现了环境隔离、快速回滚与零停机发布,适合微服务架构下的持续交付。

该方案的核心要素:
1. 多环境管理• 使用 .env 文件或配置中心(如 Consul、Apollo)按环境(dev/staging/prod)隔离配置。• CI/CD 流水线(如 GitLab CI、Jenkins)通过环境变量、分支或标签触发对应环境的构建与部署。2. Docker 集成• 每个微服务构建为独立的 Docker 镜像,打上版本号与环境标签(如 app:1.0.0-staging)。• 镜像仓库(Harbor、Docker Hub)存储所有版本。• 容器编排层(Kubernetes 或 Docker Swarm)负责调度与服务发现。3. 蓝绿部署• 维护两套完全独立的生产环境:蓝(当前运行)与绿(新版本)。• 部署新版本至绿环境,执行冒烟测试与预检。• 切换流量:通过负载均衡器(Nginx、ALB、K8s Service)将全部流量从蓝切到绿。• 保留蓝环境用于快速回滚(切换回原负载均衡规则)。4. 数据库与有状态服务处理• 采用向后兼容的数据库迁移(如增量脚本),确保蓝绿环境共享同一数据层linux操作系统下载,或对绿环境克隆数据并暂停写入。• 消息队列、缓存等通过消费者组或热备方式平滑过渡。5. 自动化流水线示例• 代码推送 → 单元测试 → 构建 Docker 镜像 → 推送到仓库 → 部署到目标环境(绿)→ 执行健康检查 → 切换负载均衡 → 监控。整体架构1. 目录结构
deploy/
├── deploy.sh # 主部署脚本
├── docker-compose.blue.yml # 蓝色环境 compose 文件
├── docker-compose.green.yml # 绿色环境 compose 文件
├── nginx/
│ └── upstream.conf # Nginx 动态上游配置
├── .env.production
├── .env.staging
└── .env.development
2. 环境配置文件示例(.env.production)
# 通用配置
APP_NAME=myapp
APP_PORT=3000
DB_HOST=prod-db.example.com
DB_PASSWORD=securepassword
# 蓝绿部署相关
ACTIVE_COLOR=blue # 当前活跃颜色(blue 或 green)
NGINX_UPSTREAM_CONF=/etc/nginx/conf.d/upstream.conf
3. Nginx 动态上游配置(nginx/upstream.conf.template)
# 这个文件会被部署脚本动态更新
upstream app_backend {
server 127.0.0.1:3001; # 蓝色实例端口
# server 127.0.0.1:3002; # 绿色实例端口
}
server {
listen 80;
server_name myapp.example.com;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

部署脚本会替换端口并重载 Nginx。
4. 蓝绿部署脚本:deploy.sh功能
#!/bin/bash
# ==================================================
# 蓝绿部署 + Docker + 多环境 脚本
# 用法: ./deploy.sh -e production -v v1.2.3
# ==================================================
set -euo pipefail
# ---------- 默认值 ----------
ENV="production"
IMAGE_VERSION="latest"
ROLLBACK=false
# ---------- 解析参数 ----------
while getopts "e:v:r" opt; do
case $opt in
e) ENV="$OPTARG" ;;
v) IMAGE_VERSION="$OPTARG" ;;
r) ROLLBACK=true ;;
*) echo "用法: $0 [-e env] [-v version] [-r]"; exit 1 ;;
esac
done
# ---------- 加载环境配置 ----------
ENV_FILE=".env.${ENV}"
if [[ ! -f "$ENV_FILE" ]]; then
echo "错误: 环境文件 $ENV_FILE 不存在"
exit 1
fi
source "$ENV_FILE"
# ---------- 颜色定义 ----------
COLOR_BLUE="blue"
COLOR_GREEN="green"
# 获取当前活跃颜色(从文件或环境变量)
ACTIVE_COLOR_FILE="/tmp/deploy_active_color_${APP_NAME}"
if [[ -f "$ACTIVE_COLOR_FILE" ]]; then
ACTIVE_COLOR=$(cat "$ACTIVE_COLOR_FILE")
else
ACTIVE_COLOR="${ACTIVE_COLOR:-blue}" # 默认蓝色
fi
if [[ "$ACTIVE_COLOR" == "$COLOR_BLUE" ]]; then
NEW_COLOR="$COLOR_GREEN"
OLD_COLOR="$COLOR_BLUE"
NEW_PORT=3002 # 绿色端口
OLD_PORT=3001 # 蓝色端口
else
NEW_COLOR="$COLOR_BLUE"
OLD_COLOR="$COLOR_GREEN"
NEW_PORT=3001
OLD_PORT=3002
fi
echo "当前活跃环境: $ACTIVE_COLOR (端口 $OLD_PORT)"
echo "将部署新版本到: $NEW_COLOR (端口 $NEW_PORT)"
# ---------- 函数:健康检查 ----------
health_check() {
local port=$1
local max_retries=30
local retry=0
echo "等待服务启动 (端口 $port)..."
until curl -s -f "http://localhost:${port}/health" > /dev/null; do
retry=$((retry+1))
if [[ $retry -ge $max_retries ]]; then
echo "健康检查失败,服务未就绪"
return 1
fi
sleep 2
done
echo "健康检查通过"
return 0
}
# ---------- 函数:切换 Nginx 上游 ----------
switch_nginx() {
local new_port=$1
local old_port=$2
local upstream_conf="${NGINX_UPSTREAM_CONF:-/etc/nginx/conf.d/upstream.conf}"
echo "更新 Nginx 配置,将流量切换到端口 $new_port"
sed -i "s/server 127.0.0.1:$old_port;/server 127.0.0.1:$new_port; # managed by deploy/" "$upstream_conf"
nginx -t && systemctl reload nginx
echo "Nginx 已重载,流量已切换"
}
# ---------- 部署新版本 ----------
deploy_new() {
local color=$1
local port=$2
local compose_file="docker-compose.${color}.yml"
# 准备 compose 文件(替换端口和版本)
cp "docker-compose.template.yml" "$compose_file"
sed -i "s/__PORT__/$port/g" "$compose_file"
sed -i "s/__IMAGE_VERSION__/$IMAGE_VERSION/g" "$compose_file"
sed -i "s/__ENV__/$ENV/g" "$compose_file"
echo "启动新版本容器 ($color) ..."
docker-compose -f "$compose_file" up -d --remove-orphans
# 健康检查
if health_check "$port"; then
echo "新版本部署成功"
return 0
else
echo "新版本健康检查失败,执行回滚"
docker-compose -f "$compose_file" down
return 1
fi
}
# ---------- 清理旧版本 ----------
cleanup_old() {
local color=$1
local compose_file="docker-compose.${color}.yml"
echo "停止并移除旧版本容器 ($color)"
docker-compose -f "$compose_file" down
}
# ---------- 主流程 ----------
if [[ "$ROLLBACK" == true ]]; then
echo "执行回滚操作:切换回 $OLD_COLOR"
switch_nginx "$OLD_PORT" "$NEW_PORT"
echo "$OLD_COLOR" > "$ACTIVE_COLOR_FILE"
exit 0
fi
# 正常部署流程
if deploy_new "$NEW_COLOR" "$NEW_PORT"; then
# 切换流量
switch_nginx "$NEW_PORT" "$OLD_PORT"
# 记录新活跃颜色
echo "$NEW_COLOR" > "$ACTIVE_COLOR_FILE"
# 清理旧版本(可选延迟清理,保留用于紧急回滚)
# cleanup_old "$OLD_COLOR"
echo "蓝绿部署完成,当前活跃: $NEW_COLOR"
else
echo "部署失败,未切换流量,服务仍使用 $OLD_COLOR"
exit 1
fi
5. Docker Compose 模板(docker-compose.template.yml)
version: '3.8'
services:
app:
image: yourregistry.com/myapp:__IMAGE_VERSION__
ports:
- "__PORT__:3000"
environment:
- NODE_ENV=__ENV__
- DB_HOST=${DB_HOST}
- DB_PASSWORD=${DB_PASSWORD}
env_file:
- .env.__ENV__
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
6. 使用步骤6.1 初始化环境
# 创建环境配置文件
cp .env.example .env.production
vim .env.production # 填写真实配置
# 准备 Nginx 上游配置(手动创建一次)
cat > /etc/nginx/conf.d/upstream.conf <<EOF
upstream app_backend {
server 127.0.0.1:3001; # 蓝色初始
}
server {
listen 80;
server_name myapp.example.com;
location / {
proxy_pass http://app_backend;
}
}
EOF
nginx -t && systemctl reload nginx
6.2 首次部署(蓝色)
# 假设镜像版本 v1.0.0
./deploy.sh -e production -v v1.0.0
# 自动启动蓝色容器,端口 3001,Nginx 指向它
6.3 升级到新版本(蓝→绿)
./deploy.sh -e production -v v1.1.0
# 脚本会启动绿色容器(端口3002),健康检查通过后切换Nginx,旧蓝色仍在运行但无流量
6.4 回滚到上一个版本
./deploy.sh -e production -r
# 切换 Nginx 回到旧端口,无需重启容器
6.5 彻底清理旧版本

部署成功后swarm2k docker界面,旧版本容器还在(方便快速回滚)。确认新版本稳定后redflag linux,手动清理:
# 查看当前活跃颜色
cat /tmp/deploy_active_color_myapp # 输出 green
# 清理蓝色容器
docker-compose -f docker-compose.blue.yml down
7. 进阶增强7.1 集成 Git 版本与镜像构建
在部署脚本开头添加:
# 如果未指定版本,从 Git commit 生成
if [[ "$IMAGE_VERSION" == "latest" ]]; then
IMAGE_VERSION=$(git rev-parse --short HEAD)
fi
# 可选:构建镜像(如果本地需要构建)
docker build -t yourregistry.com/myapp:$IMAGE_VERSION .
docker push yourregistry.com/myapp:$IMAGE_VERSION
7.2 数据库迁移处理

蓝绿部署时数据库 schema 变更可能导致新旧版本不兼容。推荐:
docker run --rm --network host yourregistry.com/myapp:$IMAGE_VERSION npm run migrate
7.3 使用 Kubernetes 实现蓝绿(更现代)
如果集群已使用 K8s,可通过修改 Service 的 selector 实现蓝绿,无需脚本管理端口。但上述 Docker Compose + Nginx 方案更轻量,适合单机或小规模部署。
8. 总结
特性
实现方式
多环境
.env.{env}
文件 + 命令行参数 -e
Docker 集成

Docker Compose 模板,通过环境变量注入配置
蓝绿部署
双套 Compose 文件,通过 Nginx 动态切换端口
健康检查

curl 探测 /health 端点
回滚
一键切回旧端口,旧容器保持运行
这套脚本可直接用于生产swarm2k docker界面,只需根据你的应用调整健康检查路径、端口、镜像仓库地址。
