diff --git a/.gitea/workflows/build-images.yaml b/.gitea/workflows/build-images.yaml index c1b1757..2dc755a 100644 --- a/.gitea/workflows/build-images.yaml +++ b/.gitea/workflows/build-images.yaml @@ -114,14 +114,8 @@ jobs: echo "====== 开始构建 Docker 镜像 ======" echo "构建时间: $(date '+%Y-%m-%d %H:%M:%S')" echo "分支: ${{ github.ref_name }}" - echo "提交: ${{ github.sha }}" - - if [ -n "${{ github.event.head_commit.message }}" ]; then - echo "提交信息: ${{ github.event.head_commit.message }}" - echo "提交者: ${{ github.event.head_commit.author.name }}" - fi - echo "" + echo "====== 构建配置 ======" echo "镜像: ${{ steps.prepare.outputs.full_image }}" echo "Dockerfile: ${{ inputs.dockerfile }}" @@ -168,37 +162,9 @@ jobs: echo "" echo "✓ 镜像验证成功" - - name: Show image details - run: | - echo "====== 镜像详细信息 ======" - docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}" | grep "${{ inputs.image_name }}" || true - echo "" - - echo "====== 镜像层信息(前10层)======" - docker history "${{ steps.prepare.outputs.full_image }}" --format "table {{.CreatedBy}}\t{{.Size}}" | head -11 - - name: Cleanup if: always() run: | echo "====== 清理悬空镜像 ======" docker image prune -f echo "✓ 清理完成" - - - name: Build summary - if: always() - run: | - echo "====== 构建摘要 ======" - echo "镜像名称: ${{ steps.prepare.outputs.full_image }}" - echo "Dockerfile: ${{ inputs.dockerfile }}" - echo "构建上下文: ${{ inputs.context }}" - echo "分支: ${{ github.ref_name }}" - echo "提交: ${{ github.sha }}" - echo "触发方式: ${{ github.event_name }}" - echo "构建状态: ${{ job.status }}" - echo "" - - if [ "${{ job.status }}" == "success" ]; then - echo "🎉 镜像构建成功!" - else - echo "❌ 镜像构建失败,请检查日志" - fi \ No newline at end of file diff --git a/.gitea/workflows/deploy-docker.yaml b/.gitea/workflows/deploy-docker.yaml new file mode 100644 index 0000000..483ab59 --- /dev/null +++ b/.gitea/workflows/deploy-docker.yaml @@ -0,0 +1,109 @@ +# .gitea/workflows/reusable-docker-deploy.yml +name: Reusable Docker Compose Deploy + +on: + workflow_call: + inputs: + compose_file: + description: 'Docker Compose 文件路径(相对于仓库根目录)' + required: true + type: string + compose_dir: + description: 'Docker Compose 工作目录(相对于仓库根目录,默认为 compose_file 所在目录)' + required: false + type: string + default: '' + checkout_ref: + description: '要检出的分支或标签' + required: false + type: string + default: '' + sparse_checkout: + description: '稀疏检出路径列表(每行一个路径)' + required: false + type: string + default: '' + enable_sparse_checkout: + description: '是否启用稀疏检出' + required: false + type: boolean + default: false + startup_wait: + description: '服务启动后等待时间(秒)' + required: false + type: number + default: 0 + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ inputs.checkout_ref || github.ref }} + sparse-checkout: ${{ inputs.enable_sparse_checkout && inputs.sparse_checkout || '' }} + sparse-checkout-cone-mode: false + fetch-depth: ${{ inputs.enable_sparse_checkout && 1 || 0 }} + + - name: Stop old services + run: | + echo "====== 停止旧服务 ======" + + cd "${{ steps.prepare.outputs.compose_dir }}" + + # 停止并移除容器 + docker compose -f "${{ steps.prepare.outputs.compose_file }}" down || true + + echo "✓ 旧服务已停止" + echo "" + + + - name: Deploy services + run: | + echo "====== 部署服务 ======" + + cd "${{ steps.prepare.outputs.compose_dir }}" + + echo "启动服务..." + docker compose -f "${{ steps.prepare.outputs.compose_file }}" up -d + + echo "✓ 服务已启动" + echo "" + + - name: Wait for services + if: ${{ inputs.startup_wait > 0 }} + run: | + echo "====== 等待服务初始化 ======" + echo "等待时间: ${{ inputs.startup_wait }} 秒" + sleep ${{ inputs.startup_wait }} + echo "✓ 等待完成" + echo "" + + - name: Verify services + run: | + echo "====== 验证服务状态 ======" + + cd "${{ steps.prepare.outputs.compose_dir }}" + + docker compose -f "${{ steps.prepare.outputs.compose_file }}" ps + echo "" + + # 检查是否有失败的服务 + FAILED_SERVICES=$(docker compose -f "${{ steps.prepare.outputs.compose_file }}" ps --status exited --format json | jq -r '.Service' 2>/dev/null || true) + + if [ -n "$FAILED_SERVICES" ]; then + echo "⚠ 以下服务启动失败:" + echo "$FAILED_SERVICES" + echo "" + echo "查看失败服务的日志:" + for service in $FAILED_SERVICES; do + echo "" + echo "=== $service 日志 ===" + docker compose -f "${{ steps.prepare.outputs.compose_file }}" logs --tail=50 "$service" + done + exit 1 + else + echo "✓ 所有服务运行正常" + fi diff --git a/.gitea/workflows/README.md b/docs/build-images.md similarity index 98% rename from .gitea/workflows/README.md rename to docs/build-images.md index aab1890..f170a18 100644 --- a/.gitea/workflows/README.md +++ b/docs/build-images.md @@ -1,4 +1,4 @@ -## WorkFlows —— Build-images.yaml调用示例 +# WorkFlows —— Build-images.yaml调用示例 ### 示例 1: 根目录 Dockerfile(broccoli-api) diff --git a/docs/deploy-docker.md b/docs/deploy-docker.md new file mode 100644 index 0000000..3bee4be --- /dev/null +++ b/docs/deploy-docker.md @@ -0,0 +1,216 @@ +# WorkFlows —— Deploy-docker.yaml调用示例 + +### 示例 1: 基本部署(broccoli-api offline 分支) + +```yaml +# .gitea/workflows/deploy-offline.yml +name: Deploy Offline Branch + +on: + push: + branches: + - offline + workflow_dispatch: + +jobs: + deploy: + uses: your-org/common-workflows/.gitea/workflows/reusable-docker-deploy.yml@main + with: + compose_file: 'docker-compose-offline.yml' + checkout_ref: 'offline' + enable_sparse_checkout: true + sparse_checkout: | + .gitea/ + config/ + docker-compose-offline.yml + cleanup_containers: true +``` + +### 示例 2: 完整部署(包含数据导入) + +```yaml +# .gitea/workflows/deploy.yml +name: Deploy Services + +on: + workflow_dispatch: + +jobs: + deploy: + uses: your-org/common-workflows/.gitea/workflows/reusable-docker-deploy.yml@main + with: + compose_file: 'docker-compose.yml' + startup_wait: 30 + run_importer: true + importer_service: 'importer' + cleanup_containers: true + cleanup_volumes: false +``` + +### 示例 3: 带环境变量的部署 + +```yaml +# .gitea/workflows/deploy-prod.yml +name: Deploy Production + +on: + workflow_dispatch: + +jobs: + deploy: + uses: your-org/common-workflows/.gitea/workflows/reusable-docker-deploy.yml@main + with: + compose_file: 'docker-compose.prod.yml' + checkout_ref: 'main' + env_vars: | + ENVIRONMENT=production + LOG_LEVEL=info + ENABLE_METRICS=true + startup_wait: 60 +``` + +### 示例 4: 子目录 Compose 文件 + +```yaml +# .gitea/workflows/deploy-services.yml +name: Deploy Microservices + +on: + workflow_dispatch: + +jobs: + deploy: + uses: your-org/common-workflows/.gitea/workflows/reusable-docker-deploy.yml@main + with: + compose_file: 'services/docker-compose.yml' + compose_dir: 'services' + enable_sparse_checkout: true + sparse_checkout: | + services/ + cleanup_containers: true +``` + +### 示例 5: 多环境部署 + +```yaml +# .gitea/workflows/deploy-multi-env.yml +name: Deploy Multiple Environments + +on: + workflow_dispatch: + inputs: + environment: + description: 'Target environment' + required: true + type: choice + options: + - dev + - staging + - prod + +jobs: + deploy-dev: + if: ${{ github.event.inputs.environment == 'dev' }} + uses: your-org/common-workflows/.gitea/workflows/reusable-docker-deploy.yml@main + with: + compose_file: 'docker-compose.dev.yml' + checkout_ref: 'develop' + cleanup_containers: true + + deploy-staging: + if: ${{ github.event.inputs.environment == 'staging' }} + uses: your-org/common-workflows/.gitea/workflows/reusable-docker-deploy.yml@main + with: + compose_file: 'docker-compose.staging.yml' + checkout_ref: 'staging' + startup_wait: 30 + cleanup_containers: true + + deploy-prod: + if: ${{ github.event.inputs.environment == 'prod' }} + uses: your-org/common-workflows/.gitea/workflows/reusable-docker-deploy.yml@main + with: + compose_file: 'docker-compose.prod.yml' + checkout_ref: 'main' + startup_wait: 60 + run_importer: true + cleanup_containers: true +``` + +### 示例 6: 完整的构建+部署流程 + +```yaml +# .gitea/workflows/ci-cd.yml +name: Build and Deploy + +on: + push: + branches: + - offline + workflow_dispatch: + +jobs: + build: + uses: your-org/common-workflows/.gitea/workflows/reusable-docker-build.yml@main + with: + dockerfile: 'Dockerfile.api' + context: '.' + image_name: 'broccoli-api' + image_tag: 'v3.2.1' + checkout_ref: 'offline' + + deploy: + needs: build + uses: your-org/common-workflows/.gitea/workflows/reusable-docker-deploy.yml@main + with: + compose_file: 'docker-compose-offline.yml' + checkout_ref: 'offline' + enable_sparse_checkout: true + sparse_checkout: | + .gitea/ + config/ + docker-compose-offline.yml + startup_wait: 30 + run_importer: true + cleanup_containers: true +``` + +### 示例 7: 仅部署特定服务 + +```yaml +# .gitea/workflows/deploy-api-only.yml +name: Deploy API Service Only + +on: + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Deploy API + run: | + docker compose -f docker-compose.yml up -d api + + # 或者调用可复用工作流处理完整流程 +``` + +## 核心特性 + +✅ **灵活配置** - 支持任意 Compose 文件路径和工作目录 +✅ **稀疏检出** - 可选的稀疏检出节省空间和时间 +✅ **资源清理** - 可控的容器和卷清理 +✅ **数据导入** - 支持一次性导入任务 +✅ **环境变量** - 支持传递部署时环境变量 +✅ **服务验证** - 自动检查服务状态并显示失败日志 +✅ **超时控制** - 可配置停止和启动等待时间 +✅ **详细日志** - 完整的部署过程和服务日志 + +这样你就有了两个专注、可复用的工作流: +1. `reusable-docker-build.yml` - 专注于镜像构建 +2. `reusable-docker-deploy.yml` - 专注于容器编排部署 + +两者可以独立使用,也可以组合成完整的 CI/CD 流程! \ No newline at end of file