init
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# 端口配置改进说明
|
||||
|
||||
## ✅ 改进内容
|
||||
|
||||
现在所有端口配置统一在 **`scripts/deploy/deploy-config.sh`** 文件中管理,只需修改一个地方即可。
|
||||
|
||||
## 📝 修改端口的方法
|
||||
|
||||
### 方法一:修改配置文件(推荐)
|
||||
|
||||
编辑 `scripts/deploy/deploy-config.sh`:
|
||||
|
||||
```bash
|
||||
vim scripts/deploy/deploy-config.sh
|
||||
|
||||
# 修改为:
|
||||
export BLUE_PORT="${BLUE_PORT:-4000}" # 蓝环境端口
|
||||
export GREEN_PORT="${GREEN_PORT:-4001}" # 绿环境端口
|
||||
export CONTAINER_PORT="${CONTAINER_PORT:-3000}" # 容器内部端口(通常不改)
|
||||
```
|
||||
|
||||
### 方法二:使用环境变量(临时)
|
||||
|
||||
```bash
|
||||
export BLUE_PORT=4000
|
||||
export GREEN_PORT=4001
|
||||
./scripts/deploy/docker-blue-green.sh
|
||||
```
|
||||
|
||||
## 🔄 自动应用的文件
|
||||
|
||||
修改配置后,以下文件会自动使用新端口:
|
||||
|
||||
1. ✅ `docker-compose.blue.yml` - 蓝环境配置
|
||||
2. ✅ `docker-compose.green.yml` - 绿环境配置
|
||||
3. ✅ `scripts/deploy/docker-blue-green.sh` - 部署脚本
|
||||
4. ✅ `scripts/deploy/rollback.sh` - 回滚脚本
|
||||
5. ✅ Nginx 配置更新(如果配置了)
|
||||
|
||||
## 📋 配置变量说明
|
||||
|
||||
- **BLUE_PORT**: 蓝环境在宿主机上映射的端口(默认 3000)
|
||||
- **GREEN_PORT**: 绿环境在宿主机上映射的端口(默认 3001)
|
||||
- **CONTAINER_PORT**: 容器内部应用监听的端口(默认 3000,通常不需要修改)
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. 修改端口后需要确保端口未被占用
|
||||
2. 如果使用 Nginx,需要更新 Nginx 配置中的 upstream
|
||||
3. 修改端口后需要重新构建和启动容器
|
||||
|
||||
## 🔍 检查端口占用
|
||||
|
||||
```bash
|
||||
# 检查端口是否被占用
|
||||
netstat -tlnp | grep 4000
|
||||
ss -tlnp | grep 4000
|
||||
```
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
# 端口配置说明
|
||||
|
||||
## 📍 统一配置端口
|
||||
|
||||
所有端口配置现在统一在 **`scripts/deploy/deploy-config.sh`** 文件中管理。
|
||||
|
||||
## 🔧 修改端口
|
||||
|
||||
只需修改 `scripts/deploy/deploy-config.sh` 文件中的端口配置:
|
||||
|
||||
```bash
|
||||
# 编辑配置文件
|
||||
vim scripts/deploy/deploy-config.sh
|
||||
|
||||
# 修改这些变量:
|
||||
export BLUE_PORT="${BLUE_PORT:-3000}" # 蓝环境端口(宿主机端口)
|
||||
export GREEN_PORT="${GREEN_PORT:-3001}" # 绿环境端口(宿主机端口)
|
||||
export CONTAINER_PORT="${CONTAINER_PORT:-3000}" # 容器内部端口(应用监听端口)
|
||||
```
|
||||
|
||||
## 📝 配置说明
|
||||
|
||||
- **BLUE_PORT**: 蓝环境在宿主机上映射的端口(默认 3000)
|
||||
- **GREEN_PORT**: 绿环境在宿主机上映射的端口(默认 3001)
|
||||
- **CONTAINER_PORT**: 容器内部应用监听的端口(默认 3000,通常不需要修改)
|
||||
|
||||
## 🔄 使用环境变量覆盖
|
||||
|
||||
也可以通过环境变量临时覆盖配置(无需修改文件):
|
||||
|
||||
```bash
|
||||
# 临时使用其他端口
|
||||
export BLUE_PORT=4000
|
||||
export GREEN_PORT=4001
|
||||
./scripts/deploy/docker-blue-green.sh
|
||||
```
|
||||
|
||||
## 📋 自动应用范围
|
||||
|
||||
修改配置后,以下文件会自动使用新端口:
|
||||
|
||||
- ✅ `docker-compose.blue.yml` - 蓝环境配置
|
||||
- ✅ `docker-compose.green.yml` - 绿环境配置
|
||||
- ✅ `scripts/deploy/docker-blue-green.sh` - 部署脚本
|
||||
- ✅ `scripts/deploy/rollback.sh` - 回滚脚本
|
||||
- ✅ Nginx 配置更新(如果配置了)
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **容器内部端口** (`CONTAINER_PORT`) 通常不需要修改,除非应用配置了其他端口
|
||||
2. **宿主机端口** (`BLUE_PORT`, `GREEN_PORT`) 需要确保端口未被占用
|
||||
3. 修改端口后,如果使用 Nginx,需要更新 Nginx 配置中的 upstream
|
||||
4. 修改端口后需要重新构建镜像和启动容器
|
||||
|
||||
## 💡 示例
|
||||
|
||||
### 修改为 4000 和 4001
|
||||
|
||||
```bash
|
||||
# 编辑配置文件
|
||||
vim scripts/deploy/deploy-config.sh
|
||||
|
||||
# 修改为:
|
||||
export BLUE_PORT="${BLUE_PORT:-4000}"
|
||||
export GREEN_PORT="${GREEN_PORT:-4001}"
|
||||
```
|
||||
|
||||
### 检查端口是否被占用
|
||||
|
||||
```bash
|
||||
# 检查端口是否被占用
|
||||
netstat -tlnp | grep 4000
|
||||
netstat -tlnp | grep 4001
|
||||
|
||||
# 或使用 ss 命令
|
||||
ss -tlnp | grep 4000
|
||||
ss -tlnp | grep 4001
|
||||
```
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
# Docker 蓝绿部署脚本
|
||||
|
||||
## 文件说明
|
||||
|
||||
- `deploy-config.sh` - **端口配置文件**(统一管理所有端口配置)
|
||||
- `docker-blue-green.sh` - 蓝绿部署主脚本,执行零停机部署
|
||||
- `git-deploy.sh` - 从 Git 拉取代码并自动部署的脚本
|
||||
- `rollback.sh` - 快速回滚到上一个版本
|
||||
- `rollback-git.sh` - 从 Git 回滚到指定版本并部署
|
||||
- `migrate.sh` - 单独执行数据库迁移脚本
|
||||
- `seed.sh` - 单独执行数据填充脚本
|
||||
|
||||
## 端口配置
|
||||
|
||||
**重要:** 所有端口配置统一在 `deploy-config.sh` 文件中管理。
|
||||
|
||||
### 修改端口
|
||||
|
||||
只需修改 `scripts/deploy/deploy-config.sh` 文件:
|
||||
|
||||
```bash
|
||||
# 编辑配置文件
|
||||
vim scripts/deploy/deploy-config.sh
|
||||
|
||||
# 修改端口配置:
|
||||
export BLUE_PORT="${BLUE_PORT:-3000}" # 蓝环境端口
|
||||
export GREEN_PORT="${GREEN_PORT:-3001}" # 绿环境端口
|
||||
export CONTAINER_PORT="${CONTAINER_PORT:-3000}" # 容器内部端口
|
||||
```
|
||||
|
||||
### 通过环境变量覆盖
|
||||
|
||||
```bash
|
||||
# 临时使用其他端口
|
||||
export BLUE_PORT=4000
|
||||
export GREEN_PORT=4001
|
||||
./scripts/deploy/docker-blue-green.sh
|
||||
```
|
||||
|
||||
详细说明请参考:`scripts/deploy/README-PORT-CONFIG.md`
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 方式一:手动部署(已拉取代码)
|
||||
|
||||
```bash
|
||||
cd /www/goravel-admin
|
||||
chmod +x scripts/deploy/docker-blue-green.sh
|
||||
./scripts/deploy/docker-blue-green.sh
|
||||
```
|
||||
|
||||
### 方式二:从 Git 拉取并部署
|
||||
|
||||
```bash
|
||||
# 设置环境变量(可选)
|
||||
export GIT_REPO_URL="https://github.com/your-username/goravel-admin.git"
|
||||
export GIT_BRANCH="main"
|
||||
export DEPLOY_DIR="/www/goravel-admin"
|
||||
|
||||
# 执行部署
|
||||
chmod +x scripts/deploy/git-deploy.sh
|
||||
./scripts/deploy/git-deploy.sh
|
||||
```
|
||||
|
||||
或者直接修改脚本中的配置:
|
||||
|
||||
```bash
|
||||
# 编辑脚本
|
||||
vim scripts/deploy/git-deploy.sh
|
||||
|
||||
# 修改这些变量:
|
||||
# GIT_REPO_URL="你的仓库地址"
|
||||
# GIT_BRANCH="main"
|
||||
# DEPLOY_DIR="/www/goravel-admin"
|
||||
```
|
||||
|
||||
## 部署流程
|
||||
|
||||
1. **检测当前版本** - 自动检测运行的是 blue 还是 green
|
||||
2. **构建新版本** - 在备用环境构建新镜像(包含启动脚本)
|
||||
3. **启动新版本** - 启动新版本容器(不同端口)
|
||||
4. **自动执行迁移** - 容器启动脚本会在应用启动前自动执行数据库迁移
|
||||
5. **数据填充(可选)** - 提示是否执行数据填充
|
||||
6. **健康检查** - 等待新版本通过健康检查
|
||||
7. **切换流量** - 更新 Nginx 配置(如果存在)
|
||||
8. **停止旧版本** - 停止旧版本容器
|
||||
|
||||
## 数据库迁移和填充
|
||||
|
||||
### 自动迁移(容器启动时执行)
|
||||
|
||||
**重要:** 迁移在容器启动时自动执行,确保在应用启动前完成:
|
||||
- ✅ **启动前执行** - 容器启动脚本会在应用启动前执行迁移,避免字段不存在错误
|
||||
- ✅ **自动执行** - 无需手动操作,每次容器启动都会执行
|
||||
- ✅ **幂等操作** - Goravel 的 `migrate` 命令是安全的,可以重复执行
|
||||
- ✅ **失败退出** - 如果迁移失败,容器会退出,部署脚本会自动检测并回滚
|
||||
- ⚙️ **可配置** - 通过环境变量 `SKIP_MIGRATE=true` 可以跳过迁移
|
||||
|
||||
### 数据填充
|
||||
|
||||
部署脚本会提示是否执行数据填充:
|
||||
- ⚠️ **需要确认** - 会提示用户是否执行
|
||||
- ⚠️ **可能重复** - 填充可能会重复插入数据,请谨慎使用
|
||||
- 💡 **建议** - 通常只在首次部署或需要更新基础数据时执行
|
||||
|
||||
### 通过环境变量控制
|
||||
|
||||
可以通过环境变量跳过填充提示:
|
||||
|
||||
```bash
|
||||
# 自动执行填充(不提示)
|
||||
export RUN_SEED=true
|
||||
./scripts/deploy/docker-blue-green.sh
|
||||
|
||||
# 跳过填充(不提示)
|
||||
export RUN_SEED=false
|
||||
./scripts/deploy/docker-blue-green.sh
|
||||
```
|
||||
|
||||
### 单独执行迁移或填充
|
||||
|
||||
如果需要单独执行迁移或填充:
|
||||
|
||||
```bash
|
||||
# 执行数据库迁移
|
||||
chmod +x scripts/deploy/migrate.sh
|
||||
./scripts/deploy/migrate.sh # 自动检测容器
|
||||
./scripts/deploy/migrate.sh goravel-admin-blue # 指定容器
|
||||
|
||||
# 执行数据填充
|
||||
chmod +x scripts/deploy/seed.sh
|
||||
./scripts/deploy/seed.sh # 自动检测容器
|
||||
./scripts/deploy/seed.sh goravel-admin-blue # 指定容器
|
||||
```
|
||||
|
||||
## 前置要求
|
||||
|
||||
- Docker 和 Docker Compose 已安装
|
||||
- 服务器上已配置 `.env` 文件
|
||||
- 如果需要 Nginx 切换,需要配置 Nginx
|
||||
|
||||
## 健康检查
|
||||
|
||||
应用需要提供 `/health` 端点,已在 `routes/web.go` 中配置。
|
||||
|
||||
## 故障处理
|
||||
|
||||
如果部署失败,脚本会自动回滚:
|
||||
- 停止新版本容器
|
||||
- 保持旧版本运行
|
||||
|
||||
## 回滚操作
|
||||
|
||||
### 快速回滚
|
||||
|
||||
如果刚部署的版本有问题,可以快速回滚到上一个版本:
|
||||
|
||||
```bash
|
||||
cd /www/goravel-admin
|
||||
chmod +x scripts/deploy/rollback.sh
|
||||
./scripts/deploy/rollback.sh
|
||||
```
|
||||
|
||||
**特点:**
|
||||
- 自动检测当前运行的版本(blue/green)
|
||||
- 切换到另一个环境
|
||||
- 如果旧容器已删除,可以选择从 Git 回滚或重新构建
|
||||
- 自动切换 Nginx 流量(如果配置了)
|
||||
|
||||
### Git 版本回滚
|
||||
|
||||
回滚到特定的 Git 提交、标签或分支:
|
||||
|
||||
```bash
|
||||
cd /www/goravel-admin
|
||||
chmod +x scripts/deploy/rollback-git.sh
|
||||
|
||||
# 查看最近提交(不带参数)
|
||||
./scripts/deploy/rollback-git.sh
|
||||
|
||||
# 回滚到上一个提交
|
||||
./scripts/deploy/rollback-git.sh HEAD~1
|
||||
|
||||
# 回滚到指定提交
|
||||
./scripts/deploy/rollback-git.sh abc1234
|
||||
|
||||
# 回滚到指定标签
|
||||
./scripts/deploy/rollback-git.sh v1.0.0
|
||||
|
||||
# 回滚到远程分支
|
||||
./scripts/deploy/rollback-git.sh origin/main
|
||||
```
|
||||
|
||||
**特点:**
|
||||
- 支持提交哈希、标签、分支
|
||||
- 自动执行部署流程
|
||||
- 需要确认操作
|
||||
|
||||
## 查看日志
|
||||
|
||||
```bash
|
||||
# 查看运行中的容器日志
|
||||
docker logs -f goravel-admin-blue
|
||||
docker logs -f goravel-admin-green
|
||||
|
||||
# 查看容器状态
|
||||
docker ps | grep goravel-admin
|
||||
|
||||
# 查看容器健康状态
|
||||
docker inspect --format='{{.State.Health.Status}}' goravel-admin-blue
|
||||
docker inspect --format='{{.State.Health.Status}}' goravel-admin-green
|
||||
```
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
# 部署配置文件
|
||||
# 在这里统一配置端口,所有脚本都会读取此配置
|
||||
|
||||
# 蓝绿部署端口配置
|
||||
export BLUE_PORT="${BLUE_PORT:-3000}" # 蓝环境端口(宿主机端口)
|
||||
export GREEN_PORT="${GREEN_PORT:-3001}" # 绿环境端口(宿主机端口)
|
||||
export CONTAINER_PORT="${CONTAINER_PORT:-3000}" # 容器内部端口(应用监听端口)
|
||||
|
||||
# 其他配置
|
||||
export DEPLOY_DIR="${DEPLOY_DIR:-/www/goravel-admin}"
|
||||
export NGINX_CONF="${NGINX_CONF:-/etc/nginx/sites-available/goravel-admin}"
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
#!/bin/bash
|
||||
# Docker Compose 蓝绿部署脚本
|
||||
# 在服务器上执行此脚本
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR/../../" # 回到项目根目录
|
||||
|
||||
# 加载部署配置
|
||||
source "$SCRIPT_DIR/deploy-config.sh"
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 检测当前运行的版本
|
||||
detect_current_version() {
|
||||
if docker ps --format "{{.Names}}" | grep -q "goravel-admin-blue"; then
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' goravel-admin-blue 2>/dev/null)" = "true" ]; then
|
||||
echo "blue"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
if docker ps --format "{{.Names}}" | grep -q "goravel-admin-green"; then
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' goravel-admin-green 2>/dev/null)" = "true" ]; then
|
||||
echo "green"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
echo "blue" # 默认从 blue 开始
|
||||
}
|
||||
|
||||
CURRENT_COLOR=$(detect_current_version)
|
||||
NEXT_COLOR=$([ "$CURRENT_COLOR" = "blue" ] && echo "green" || echo "blue")
|
||||
CURRENT_PORT=$([ "$CURRENT_COLOR" = "blue" ] && echo "$BLUE_PORT" || echo "$GREEN_PORT")
|
||||
NEXT_PORT=$([ "$NEXT_COLOR" = "blue" ] && echo "$BLUE_PORT" || echo "$GREEN_PORT")
|
||||
|
||||
echo -e "${GREEN}=== Docker Compose 蓝绿部署 ===${NC}"
|
||||
echo -e "当前运行: ${YELLOW}$CURRENT_COLOR${NC} (端口: $CURRENT_PORT)"
|
||||
echo -e "部署到: ${YELLOW}$NEXT_COLOR${NC} (端口: $NEXT_PORT)"
|
||||
echo ""
|
||||
|
||||
# 1. 检查 Docker 和 Docker Compose
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo -e "${RED}错误: Docker 未安装${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
|
||||
echo -e "${RED}错误: Docker Compose 未安装${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 使用 docker compose 或 docker-compose
|
||||
COMPOSE_CMD="docker-compose"
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
COMPOSE_CMD="docker compose"
|
||||
fi
|
||||
|
||||
# 导出端口配置到环境变量(供 docker-compose 使用)
|
||||
export BLUE_PORT GREEN_PORT CONTAINER_PORT
|
||||
|
||||
# 2. 构建新版本镜像
|
||||
echo -e "${GREEN}[1/7] 构建新版本镜像...${NC}"
|
||||
echo "注意: 镜像包含启动脚本,会在应用启动前自动执行数据库迁移"
|
||||
$COMPOSE_CMD -f docker-compose.${NEXT_COLOR}.yml build --no-cache
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}构建失败!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. 启动新版本容器
|
||||
echo -e "${GREEN}[2/7] 启动新版本容器 (端口 $NEXT_PORT)...${NC}"
|
||||
$COMPOSE_CMD -f docker-compose.${NEXT_COLOR}.yml up -d
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}启动失败!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 4. 等待容器启动(启动脚本会自动执行迁移)
|
||||
echo -e "${GREEN}[3/7] 等待容器启动并执行迁移...${NC}"
|
||||
echo "注意: 容器启动脚本会在应用启动前自动执行数据库迁移"
|
||||
|
||||
# 等待容器启动并完成迁移
|
||||
# 启动脚本会在应用启动前执行迁移,所以我们需要等待应用完全启动
|
||||
for i in {1..30}; do
|
||||
# 检查容器是否运行
|
||||
if ! docker ps --format "{{.Names}}" | grep -q "goravel-admin-${NEXT_COLOR}"; then
|
||||
echo "容器未运行,等待中... ($i/30)"
|
||||
sleep 2
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检查应用是否已启动(迁移完成后应用才会启动)
|
||||
if docker exec goravel-admin-${NEXT_COLOR} /www/main artisan --version > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✓ 容器已启动,迁移已完成,应用已就绪${NC}"
|
||||
break
|
||||
fi
|
||||
|
||||
if [ $i -eq 30 ]; then
|
||||
echo -e "${RED}✗ 容器启动超时,可能迁移失败${NC}"
|
||||
echo "查看容器日志:"
|
||||
docker logs --tail 50 goravel-admin-${NEXT_COLOR}
|
||||
$COMPOSE_CMD -f docker-compose.${NEXT_COLOR}.yml down
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "等待容器启动和迁移完成... ($i/30)"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# 验证迁移是否成功(可选,作为双重检查)
|
||||
echo "验证数据库迁移状态..."
|
||||
if docker exec goravel-admin-${NEXT_COLOR} /www/main artisan migrate:status > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✓ 数据库迁移验证通过${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}警告: 无法验证迁移状态,但应用已启动${NC}"
|
||||
fi
|
||||
|
||||
# 6. 询问是否执行数据填充(可选)
|
||||
echo -e "${GREEN}[5/7] 数据填充(可选)...${NC}"
|
||||
if [ -z "$RUN_SEED" ]; then
|
||||
read -p "是否执行数据填充?这可能会重复插入数据 (y/N): " seed_confirm
|
||||
if [ "$seed_confirm" = "y" ] || [ "$seed_confirm" = "Y" ]; then
|
||||
RUN_SEED="true"
|
||||
else
|
||||
RUN_SEED="false"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$RUN_SEED" = "true" ]; then
|
||||
echo "执行数据填充..."
|
||||
if docker exec goravel-admin-${NEXT_COLOR} /www/main artisan db:seed; then
|
||||
echo -e "${GREEN}✓ 数据填充成功${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}警告: 数据填充失败,但继续部署${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}跳过数据填充${NC}"
|
||||
fi
|
||||
|
||||
# 7. 健康检查
|
||||
echo -e "${GREEN}[6/7] 执行健康检查...${NC}"
|
||||
HEALTH_CHECK_FAILED=true
|
||||
for i in {1..30}; do
|
||||
# 检查容器是否运行
|
||||
if ! docker ps --format "{{.Names}}" | grep -q "goravel-admin-${NEXT_COLOR}"; then
|
||||
echo "容器未运行,等待中... ($i/30)"
|
||||
sleep 2
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检查健康状态
|
||||
HEALTH=$(docker inspect --format='{{.State.Health.Status}}' goravel-admin-${NEXT_COLOR} 2>/dev/null || echo "none")
|
||||
|
||||
# 尝试 HTTP 健康检查
|
||||
if curl -f -s http://localhost:$NEXT_PORT/health > /dev/null 2>&1 || \
|
||||
curl -f -s http://localhost:$NEXT_PORT/ > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✓ 新版本健康检查通过 (尝试 $i/30)${NC}"
|
||||
HEALTH_CHECK_FAILED=false
|
||||
break
|
||||
fi
|
||||
|
||||
if [ "$HEALTH" = "healthy" ]; then
|
||||
echo -e "${GREEN}✓ 新版本健康检查通过 (Docker 健康检查)${NC}"
|
||||
HEALTH_CHECK_FAILED=false
|
||||
break
|
||||
fi
|
||||
|
||||
echo "等待健康检查... ($i/30)"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ "$HEALTH_CHECK_FAILED" = "true" ]; then
|
||||
echo -e "${RED}✗ 健康检查失败,停止新版本并回滚${NC}"
|
||||
$COMPOSE_CMD -f docker-compose.${NEXT_COLOR}.yml down
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 8. 切换 Nginx 流量(如果有 Nginx)
|
||||
echo -e "${GREEN}[7/7] 切换 Nginx 流量...${NC}"
|
||||
NGINX_CONF="/etc/nginx/sites-available/goravel-admin"
|
||||
if [ -f "$NGINX_CONF" ]; then
|
||||
# 备份配置
|
||||
BACKUP_FILE="${NGINX_CONF}.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
cp "$NGINX_CONF" "$BACKUP_FILE"
|
||||
echo "已备份 Nginx 配置到: $BACKUP_FILE"
|
||||
|
||||
# 更新 upstream 配置
|
||||
sed -i "s/server 127.0.0.1:$BLUE_PORT/server 127.0.0.1:$NEXT_PORT/" "$NGINX_CONF"
|
||||
sed -i "s/server 127.0.0.1:$GREEN_PORT/server 127.0.0.1:$NEXT_PORT/" "$NGINX_CONF"
|
||||
|
||||
# 测试并重载 Nginx
|
||||
if nginx -t 2>/dev/null; then
|
||||
nginx -s reload
|
||||
echo -e "${GREEN}✓ Nginx 流量已切换到端口 $NEXT_PORT${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}警告: Nginx 配置测试失败,恢复备份${NC}"
|
||||
mv "$BACKUP_FILE" "$NGINX_CONF"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}提示: Nginx 配置文件不存在,跳过流量切换${NC}"
|
||||
echo -e "${YELLOW}请手动配置负载均衡指向端口 $NEXT_PORT${NC}"
|
||||
fi
|
||||
|
||||
# 9. 等待流量切换完成
|
||||
echo -e "${GREEN}等待流量切换完成...${NC}"
|
||||
sleep 5
|
||||
|
||||
# 10. 停止旧版本服务
|
||||
echo -e "${GREEN}停止旧版本服务 ($CURRENT_COLOR)...${NC}"
|
||||
$COMPOSE_CMD -f docker-compose.${CURRENT_COLOR}.yml down
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}=== 部署完成 ===${NC}"
|
||||
echo -e "当前运行版本: ${YELLOW}$NEXT_COLOR${NC} (端口: $NEXT_PORT)"
|
||||
echo -e "旧版本: ${YELLOW}$CURRENT_COLOR${NC} (已停止)"
|
||||
echo ""
|
||||
echo "查看日志: docker logs -f goravel-admin-${NEXT_COLOR}"
|
||||
echo "查看状态: docker ps | grep goravel-admin"
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
# 从 Git 拉取代码并部署
|
||||
# 在服务器上执行此脚本
|
||||
|
||||
set -e
|
||||
|
||||
# 配置(根据实际情况修改)
|
||||
GIT_REPO_URL="${GIT_REPO_URL:-https://github.com/your-username/goravel-admin.git}" # 修改为你的 Git 仓库
|
||||
GIT_BRANCH="${GIT_BRANCH:-main}" # 或 master
|
||||
DEPLOY_DIR="${DEPLOY_DIR:-/www/goravel-admin}"
|
||||
|
||||
# 颜色输出
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${GREEN}=== 从 Git 拉取并部署 ===${NC}"
|
||||
echo "仓库: $GIT_REPO_URL"
|
||||
echo "分支: $GIT_BRANCH"
|
||||
echo "目录: $DEPLOY_DIR"
|
||||
echo ""
|
||||
|
||||
# 1. 检查部署目录
|
||||
if [ ! -d "$DEPLOY_DIR" ]; then
|
||||
echo "创建部署目录: $DEPLOY_DIR"
|
||||
mkdir -p "$DEPLOY_DIR"
|
||||
fi
|
||||
|
||||
cd "$DEPLOY_DIR"
|
||||
|
||||
# 2. 如果是第一次,克隆仓库
|
||||
if [ ! -d ".git" ]; then
|
||||
echo -e "${GREEN}首次部署,克隆仓库...${NC}"
|
||||
if [ -z "$GIT_REPO_URL" ] || [ "$GIT_REPO_URL" = "https://github.com/your-username/goravel-admin.git" ]; then
|
||||
echo -e "${RED}错误: 请设置 GIT_REPO_URL 环境变量或修改脚本中的仓库地址${NC}"
|
||||
exit 1
|
||||
fi
|
||||
git clone -b "$GIT_BRANCH" "$GIT_REPO_URL" .
|
||||
else
|
||||
echo -e "${GREEN}拉取最新代码...${NC}"
|
||||
git fetch origin
|
||||
git reset --hard origin/$GIT_BRANCH
|
||||
git pull origin $GIT_BRANCH || {
|
||||
echo -e "${YELLOW}警告: git pull 失败,尝试强制重置${NC}"
|
||||
git fetch origin
|
||||
git reset --hard origin/$GIT_BRANCH
|
||||
}
|
||||
fi
|
||||
|
||||
# 3. 检查必要文件
|
||||
if [ ! -f "Dockerfile" ]; then
|
||||
echo -e "${RED}错误: 未找到 Dockerfile${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "docker-compose.blue.yml" ] || [ ! -f "docker-compose.green.yml" ]; then
|
||||
echo -e "${RED}错误: 未找到 Docker Compose 配置文件${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 4. 确保 .env 文件存在
|
||||
if [ ! -f ".env" ]; then
|
||||
echo -e "${YELLOW}警告: .env 文件不存在${NC}"
|
||||
if [ -f ".env.example" ]; then
|
||||
echo "从 .env.example 复制..."
|
||||
cp .env.example .env
|
||||
echo -e "${YELLOW}请编辑 .env 文件并设置正确的配置${NC}"
|
||||
else
|
||||
echo -e "${RED}错误: 未找到 .env 或 .env.example 文件${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 5. 确保部署脚本可执行
|
||||
if [ -f "scripts/deploy/docker-blue-green.sh" ]; then
|
||||
chmod +x scripts/deploy/docker-blue-green.sh
|
||||
echo -e "${GREEN}执行部署脚本...${NC}"
|
||||
./scripts/deploy/docker-blue-green.sh
|
||||
else
|
||||
echo -e "${RED}错误: 未找到 deploy.sh${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}=== 部署完成 ===${NC}"
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
# 数据库迁移脚本
|
||||
# 在运行中的容器中执行数据库迁移
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
# 检测当前运行的版本
|
||||
detect_current_version() {
|
||||
if docker ps --format "{{.Names}}" | grep -q "goravel-admin-blue"; then
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' goravel-admin-blue 2>/dev/null)" = "true" ]; then
|
||||
echo "blue"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
if docker ps --format "{{.Names}}" | grep -q "goravel-admin-green"; then
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' goravel-admin-green 2>/dev/null)" = "true" ]; then
|
||||
echo "green"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
echo "none"
|
||||
}
|
||||
|
||||
CONTAINER_NAME=$1
|
||||
|
||||
# 如果没有指定容器名,自动检测
|
||||
if [ -z "$CONTAINER_NAME" ]; then
|
||||
CURRENT_COLOR=$(detect_current_version)
|
||||
if [ "$CURRENT_COLOR" = "none" ]; then
|
||||
echo -e "${RED}错误: 未找到运行中的容器${NC}"
|
||||
echo "用法: $0 <container-name>"
|
||||
echo "示例: $0 goravel-admin-blue"
|
||||
exit 1
|
||||
fi
|
||||
CONTAINER_NAME="goravel-admin-${CURRENT_COLOR}"
|
||||
echo -e "${YELLOW}自动检测到运行中的容器: $CONTAINER_NAME${NC}"
|
||||
fi
|
||||
|
||||
# 检查容器是否存在
|
||||
if ! docker ps --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then
|
||||
echo -e "${RED}错误: 容器 $CONTAINER_NAME 不存在或未运行${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}=== 执行数据库迁移 ===${NC}"
|
||||
echo -e "容器: ${YELLOW}$CONTAINER_NAME${NC}"
|
||||
echo ""
|
||||
|
||||
# 执行迁移
|
||||
echo "执行数据库迁移..."
|
||||
if docker exec $CONTAINER_NAME /www/main artisan migrate; then
|
||||
echo -e "${GREEN}✓ 数据库迁移成功${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}✗ 数据库迁移失败${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
# 从 Git 回滚到指定版本并部署
|
||||
# 用于回滚到特定的 Git 提交
|
||||
|
||||
set -e
|
||||
|
||||
# 配置
|
||||
GIT_BRANCH="${GIT_BRANCH:-main}"
|
||||
DEPLOY_DIR="${DEPLOY_DIR:-/www/goravel-admin}"
|
||||
|
||||
# 颜色输出
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${YELLOW}=== Git 版本回滚 ===${NC}"
|
||||
|
||||
# 检查参数
|
||||
if [ -z "$1" ]; then
|
||||
echo -e "${BLUE}用法: $0 <commit-hash|tag|branch>${NC}"
|
||||
echo "示例:"
|
||||
echo " $0 abc1234 # 回滚到指定提交"
|
||||
echo " $0 v1.0.0 # 回滚到指定标签"
|
||||
echo " $0 HEAD~1 # 回滚到上一个提交"
|
||||
echo " $0 origin/main # 回滚到远程分支"
|
||||
echo ""
|
||||
echo -e "${YELLOW}最近的提交历史:${NC}"
|
||||
cd "$DEPLOY_DIR" 2>/dev/null || cd "$(dirname "$0")/../../"
|
||||
git log --oneline -10 2>/dev/null || echo "无法获取 Git 历史"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_VERSION="$1"
|
||||
|
||||
# 检查部署目录
|
||||
if [ ! -d "$DEPLOY_DIR" ]; then
|
||||
# 尝试使用当前目录
|
||||
if [ -d ".git" ]; then
|
||||
DEPLOY_DIR="$(pwd)"
|
||||
else
|
||||
echo -e "${RED}错误: 部署目录不存在: $DEPLOY_DIR${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
cd "$DEPLOY_DIR"
|
||||
|
||||
# 检查是否是 Git 仓库
|
||||
if [ ! -d ".git" ]; then
|
||||
echo -e "${RED}错误: 当前目录不是 Git 仓库${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 显示当前状态
|
||||
CURRENT_COMMIT=$(git rev-parse --short HEAD)
|
||||
echo -e "当前提交: ${YELLOW}$CURRENT_COMMIT${NC}"
|
||||
echo -e "目标版本: ${YELLOW}$TARGET_VERSION${NC}"
|
||||
echo ""
|
||||
|
||||
# 确认回滚
|
||||
read -p "确认要回滚到 $TARGET_VERSION 吗? (y/N): " confirm
|
||||
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
|
||||
echo -e "${YELLOW}取消回滚${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 检查目标版本是否存在
|
||||
if ! git rev-parse --verify "$TARGET_VERSION" > /dev/null 2>&1; then
|
||||
echo -e "${RED}错误: 未找到版本 $TARGET_VERSION${NC}"
|
||||
echo -e "${YELLOW}提示: 尝试先执行 git fetch origin${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 回滚到目标版本
|
||||
echo -e "${GREEN}回滚到 $TARGET_VERSION...${NC}"
|
||||
git fetch origin 2>/dev/null || true
|
||||
git checkout "$TARGET_VERSION"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}回滚失败!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NEW_COMMIT=$(git rev-parse --short HEAD)
|
||||
echo -e "${GREEN}✓ 已回滚到 $NEW_COMMIT${NC}"
|
||||
echo ""
|
||||
|
||||
# 执行部署
|
||||
if [ -f "scripts/deploy/docker-blue-green.sh" ]; then
|
||||
echo -e "${GREEN}执行部署...${NC}"
|
||||
chmod +x scripts/deploy/docker-blue-green.sh
|
||||
./scripts/deploy/docker-blue-green.sh
|
||||
else
|
||||
echo -e "${RED}错误: 未找到部署脚本${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}=== Git 回滚完成 ===${NC}"
|
||||
echo -e "当前版本: ${YELLOW}$NEW_COMMIT${NC}"
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
#!/bin/bash
|
||||
# Docker Compose 蓝绿部署回滚脚本
|
||||
# 快速回滚到上一个版本
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR/../../" # 回到项目根目录
|
||||
|
||||
# 加载部署配置
|
||||
source "$SCRIPT_DIR/deploy-config.sh"
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 检测当前运行的版本
|
||||
detect_current_version() {
|
||||
if docker ps --format "{{.Names}}" | grep -q "goravel-admin-blue"; then
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' goravel-admin-blue 2>/dev/null)" = "true" ]; then
|
||||
echo "blue"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
if docker ps --format "{{.Names}}" | grep -q "goravel-admin-green"; then
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' goravel-admin-green 2>/dev/null)" = "true" ]; then
|
||||
echo "green"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
echo "none"
|
||||
}
|
||||
|
||||
CURRENT_COLOR=$(detect_current_version)
|
||||
|
||||
if [ "$CURRENT_COLOR" = "none" ]; then
|
||||
echo -e "${RED}错误: 未检测到运行中的容器${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PREVIOUS_COLOR=$([ "$CURRENT_COLOR" = "blue" ] && echo "green" || echo "blue")
|
||||
CURRENT_PORT=$([ "$CURRENT_COLOR" = "blue" ] && echo "$BLUE_PORT" || echo "$GREEN_PORT")
|
||||
PREVIOUS_PORT=$([ "$PREVIOUS_COLOR" = "blue" ] && echo "$BLUE_PORT" || echo "$GREEN_PORT")
|
||||
|
||||
echo -e "${YELLOW}=== Docker Compose 蓝绿部署回滚 ===${NC}"
|
||||
echo -e "当前运行: ${YELLOW}$CURRENT_COLOR${NC} (端口: $CURRENT_PORT)"
|
||||
echo -e "回滚到: ${YELLOW}$PREVIOUS_COLOR${NC} (端口: $PREVIOUS_PORT)"
|
||||
echo ""
|
||||
|
||||
# 检查 Docker 和 Docker Compose
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo -e "${RED}错误: Docker 未安装${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
|
||||
echo -e "${RED}错误: Docker Compose 未安装${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 使用 docker compose 或 docker-compose
|
||||
COMPOSE_CMD="docker-compose"
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
COMPOSE_CMD="docker compose"
|
||||
fi
|
||||
|
||||
# 导出端口配置到环境变量(供 docker-compose 使用)
|
||||
export BLUE_PORT GREEN_PORT CONTAINER_PORT
|
||||
|
||||
# 检查上一个版本的容器是否存在(可能已停止但未删除)
|
||||
PREVIOUS_CONTAINER_EXISTS=false
|
||||
if docker ps -a --format "{{.Names}}" | grep -q "goravel-admin-${PREVIOUS_COLOR}"; then
|
||||
PREVIOUS_CONTAINER_EXISTS=true
|
||||
fi
|
||||
|
||||
# 如果上一个版本的容器不存在,需要重新构建
|
||||
if [ "$PREVIOUS_CONTAINER_EXISTS" = "false" ]; then
|
||||
echo -e "${YELLOW}警告: 上一个版本的容器不存在,需要重新构建${NC}"
|
||||
echo -e "${BLUE}选项:${NC}"
|
||||
echo "1. 从 Git 回滚到上一个提交并重新构建"
|
||||
echo "2. 使用当前代码重新构建上一个版本"
|
||||
echo "3. 取消回滚"
|
||||
read -p "请选择 (1/2/3): " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
echo -e "${GREEN}从 Git 回滚...${NC}"
|
||||
read -p "请输入要回滚的 Git 提交哈希 (或按 Enter 使用 HEAD~1): " commit_hash
|
||||
commit_hash=${commit_hash:-HEAD~1}
|
||||
git checkout $commit_hash
|
||||
echo -e "${GREEN}构建回滚版本...${NC}"
|
||||
$COMPOSE_CMD -f docker-compose.${PREVIOUS_COLOR}.yml build --no-cache
|
||||
;;
|
||||
2)
|
||||
echo -e "${GREEN}使用当前代码重新构建...${NC}"
|
||||
$COMPOSE_CMD -f docker-compose.${PREVIOUS_COLOR}.yml build --no-cache
|
||||
;;
|
||||
3)
|
||||
echo -e "${YELLOW}取消回滚${NC}"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}无效选择${NC}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# 1. 启动上一个版本
|
||||
echo -e "${GREEN}[1/4] 启动上一个版本容器 (端口 $PREVIOUS_PORT)...${NC}"
|
||||
$COMPOSE_CMD -f docker-compose.${PREVIOUS_COLOR}.yml up -d
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}启动失败!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. 等待容器启动
|
||||
echo -e "${GREEN}[2/4] 等待容器启动...${NC}"
|
||||
sleep 5
|
||||
|
||||
# 3. 健康检查
|
||||
echo -e "${GREEN}[3/4] 执行健康检查...${NC}"
|
||||
HEALTH_CHECK_FAILED=true
|
||||
for i in {1..30}; do
|
||||
# 检查容器是否运行
|
||||
if ! docker ps --format "{{.Names}}" | grep -q "goravel-admin-${PREVIOUS_COLOR}"; then
|
||||
echo "容器未运行,等待中... ($i/30)"
|
||||
sleep 2
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检查健康状态
|
||||
HEALTH=$(docker inspect --format='{{.State.Health.Status}}' goravel-admin-${PREVIOUS_COLOR} 2>/dev/null || echo "none")
|
||||
|
||||
# 尝试 HTTP 健康检查
|
||||
if curl -f -s http://localhost:$PREVIOUS_PORT/health > /dev/null 2>&1 || \
|
||||
curl -f -s http://localhost:$PREVIOUS_PORT/ > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✓ 回滚版本健康检查通过 (尝试 $i/30)${NC}"
|
||||
HEALTH_CHECK_FAILED=false
|
||||
break
|
||||
fi
|
||||
|
||||
if [ "$HEALTH" = "healthy" ]; then
|
||||
echo -e "${GREEN}✓ 回滚版本健康检查通过 (Docker 健康检查)${NC}"
|
||||
HEALTH_CHECK_FAILED=false
|
||||
break
|
||||
fi
|
||||
|
||||
echo "等待健康检查... ($i/30)"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ "$HEALTH_CHECK_FAILED" = "true" ]; then
|
||||
echo -e "${RED}✗ 健康检查失败,回滚中止${NC}"
|
||||
echo -e "${YELLOW}保持当前版本运行${NC}"
|
||||
$COMPOSE_CMD -f docker-compose.${PREVIOUS_COLOR}.yml down
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 4. 切换 Nginx 流量
|
||||
echo -e "${GREEN}[4/4] 切换 Nginx 流量...${NC}"
|
||||
NGINX_CONF="/etc/nginx/sites-available/goravel-admin"
|
||||
if [ -f "$NGINX_CONF" ]; then
|
||||
# 备份配置
|
||||
BACKUP_FILE="${NGINX_CONF}.backup.rollback.$(date +%Y%m%d_%H%M%S)"
|
||||
cp "$NGINX_CONF" "$BACKUP_FILE"
|
||||
echo "已备份 Nginx 配置到: $BACKUP_FILE"
|
||||
|
||||
# 更新 upstream 配置
|
||||
sed -i "s/server 127.0.0.1:$BLUE_PORT/server 127.0.0.1:$PREVIOUS_PORT/" "$NGINX_CONF"
|
||||
sed -i "s/server 127.0.0.1:$GREEN_PORT/server 127.0.0.1:$PREVIOUS_PORT/" "$NGINX_CONF"
|
||||
|
||||
# 测试并重载 Nginx
|
||||
if nginx -t 2>/dev/null; then
|
||||
nginx -s reload
|
||||
echo -e "${GREEN}✓ Nginx 流量已切换到端口 $PREVIOUS_PORT${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}警告: Nginx 配置测试失败,恢复备份${NC}"
|
||||
mv "$BACKUP_FILE" "$NGINX_CONF"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}提示: Nginx 配置文件不存在,跳过流量切换${NC}"
|
||||
echo -e "${YELLOW}请手动配置负载均衡指向端口 $PREVIOUS_PORT${NC}"
|
||||
fi
|
||||
|
||||
# 5. 等待流量切换完成
|
||||
echo -e "${GREEN}等待流量切换完成...${NC}"
|
||||
sleep 5
|
||||
|
||||
# 6. 停止当前版本
|
||||
echo -e "${GREEN}停止当前版本 ($CURRENT_COLOR)...${NC}"
|
||||
$COMPOSE_CMD -f docker-compose.${CURRENT_COLOR}.yml down
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}=== 回滚完成 ===${NC}"
|
||||
echo -e "当前运行版本: ${YELLOW}$PREVIOUS_COLOR${NC} (端口: $PREVIOUS_PORT)"
|
||||
echo -e "已停止版本: ${YELLOW}$CURRENT_COLOR${NC}"
|
||||
echo ""
|
||||
echo "查看日志: docker logs -f goravel-admin-${PREVIOUS_COLOR}"
|
||||
echo "查看状态: docker ps | grep goravel-admin"
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
# 数据填充脚本
|
||||
# 在运行中的容器中执行数据填充
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
# 检测当前运行的版本
|
||||
detect_current_version() {
|
||||
if docker ps --format "{{.Names}}" | grep -q "goravel-admin-blue"; then
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' goravel-admin-blue 2>/dev/null)" = "true" ]; then
|
||||
echo "blue"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
if docker ps --format "{{.Names}}" | grep -q "goravel-admin-green"; then
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' goravel-admin-green 2>/dev/null)" = "true" ]; then
|
||||
echo "green"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
echo "none"
|
||||
}
|
||||
|
||||
CONTAINER_NAME=$1
|
||||
|
||||
# 如果没有指定容器名,自动检测
|
||||
if [ -z "$CONTAINER_NAME" ]; then
|
||||
CURRENT_COLOR=$(detect_current_version)
|
||||
if [ "$CURRENT_COLOR" = "none" ]; then
|
||||
echo -e "${RED}错误: 未找到运行中的容器${NC}"
|
||||
echo "用法: $0 <container-name>"
|
||||
echo "示例: $0 goravel-admin-blue"
|
||||
exit 1
|
||||
fi
|
||||
CONTAINER_NAME="goravel-admin-${CURRENT_COLOR}"
|
||||
echo -e "${YELLOW}自动检测到运行中的容器: $CONTAINER_NAME${NC}"
|
||||
fi
|
||||
|
||||
# 检查容器是否存在
|
||||
if ! docker ps --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then
|
||||
echo -e "${RED}错误: 容器 $CONTAINER_NAME 不存在或未运行${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}=== 执行数据填充 ===${NC}"
|
||||
echo -e "容器: ${YELLOW}$CONTAINER_NAME${NC}"
|
||||
echo -e "${YELLOW}警告: 数据填充可能会重复插入数据${NC}"
|
||||
echo ""
|
||||
|
||||
# 确认操作
|
||||
read -p "确认要执行数据填充吗?(y/N): " confirm
|
||||
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
|
||||
echo -e "${YELLOW}取消数据填充${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 执行填充
|
||||
echo "执行数据填充..."
|
||||
if docker exec $CONTAINER_NAME /www/main artisan db:seed; then
|
||||
echo -e "${GREEN}✓ 数据填充成功${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}✗ 数据填充失败${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user