fix(ci): trap EXIT 回收集成测试 PG/Redis 容器,杜绝取消/失败泄漏 #1946

Merged
xiaoxia merged 2 commits from fix/ci-service-container-cleanup-trap into develop 2026-09-16 06:52:20 +08:00
Owner

背景

9/15 CI 大面积排队,根因是集成测试的临时服务容器(ci-pg-/ci-redis-)在 job 失败或被取消时不回收,堆积 20 个僵尸容器把构建机 load 顶到 25.9。

根因

scripts/ci/run_integration_tests.shdocker run -d 起 PG/Redis,只在脚本正常走到结尾时 docker rm -fset -e 中途失败或 Gitea 取消(SIGTERM)时清理不执行 → 泄漏。

改动

  • 新增幂等 cleanup_containers(),注册 trap EXIT / INT / TERM,在启动任何服务容器前生效
  • 任何退出路径(成功/失败/取消)都回收临时 PG、Redis 容器,并保留原始退出码
  • 共享 PG(CI_USE_SHARED_PG=true)的 drop-db 逻辑保持不变
  • 参照 validate_migration.sh 已有的 trap cleanup_db EXIT 做法

配套(主机侧,已上线)

/opt/scripts/ci_service_reaper.py 每 5 分钟按 Gitea run 状态兜底回收泄漏容器(run 完成即清,在跑的保留),作为第二层防御。

风险

仅改测试脚本清理逻辑,不碰业务代码。bash -n 通过。

## 背景 9/15 CI 大面积排队,根因是集成测试的临时服务容器(ci-pg-/ci-redis-)在 job **失败或被取消**时不回收,堆积 20 个僵尸容器把构建机 load 顶到 25.9。 ## 根因 `scripts/ci/run_integration_tests.sh` 用 `docker run -d` 起 PG/Redis,只在脚本正常走到结尾时 `docker rm -f`;`set -e` 中途失败或 Gitea 取消(SIGTERM)时清理不执行 → 泄漏。 ## 改动 - 新增幂等 `cleanup_containers()`,注册 `trap EXIT / INT / TERM`,在启动任何服务容器前生效 - 任何退出路径(成功/失败/取消)都回收临时 PG、Redis 容器,并保留原始退出码 - 共享 PG(CI_USE_SHARED_PG=true)的 drop-db 逻辑保持不变 - 参照 `validate_migration.sh` 已有的 `trap cleanup_db EXIT` 做法 ## 配套(主机侧,已上线) `/opt/scripts/ci_service_reaper.py` 每 5 分钟按 Gitea run 状态兜底回收泄漏容器(run 完成即清,在跑的保留),作为第二层防御。 ## 风险 仅改测试脚本清理逻辑,不碰业务代码。bash -n 通过。
xiaoxia added 1 commit 2026-09-16 00:18:16 +08:00
fix(ci): trap EXIT 回收集成测试 PG/Redis 容器,杜绝取消/失败时泄漏
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Has been cancelled
CI/CD Pipeline / Check if frontend-only change (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been cancelled
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / PR Build API Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Web Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Check push changed paths (pull_request) Has been cancelled
CI/CD Pipeline / Build Staging API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
AI Code Review / AI Code Review (pull_request) Has been cancelled
PR Automation / Auto Approve on CI Green (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
Preview Deploy / Deploy Preview Environment (pull_request) Has been cancelled
371be8034d
问题:run_integration_tests.sh 用 docker run -d 起 ci-pg-/ci-redis- 服务容器,
仅在脚本正常走到结尾时 rm;job 失败(set -e)或被 Gitea 取消(SIGTERM)时容器
永久残留。2026-09-15 堆积 20 个泄漏容器把构建机 load 顶到 25.9,CI 大面积排队。

修复:参照 validate_migration.sh 既有做法,新增幂等 cleanup_containers 并注册
trap EXIT/INT/TERM,在启动服务容器前生效,保证任何退出路径都回收临时容器;
共享 PG 模式的 drop-db 逻辑保持不变。主机侧另有 ci_service_reaper.py 每5分钟兜底。
xiaoxia added 1 commit 2026-09-16 00:19:09 +08:00
fix(ci): run_staging_tests.sh 同样加 trap EXIT 回收 staging 测试容器
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m47s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m51s
AI Code Review / AI Code Review (pull_request) Successful in 6m21s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 16m55s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 0s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 2m3s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 2m39s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 3m54s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 5m7s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 10m1s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 10m44s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 12m24s
CI/CD Pipeline / CI Gate (pull_request) Successful in 2s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 22s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 52s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 8h40m31s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 8h51m17s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 8h40m28s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 8h51m16s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 8h50m33s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 8h50m33s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 8h39m47s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 8h39m47s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 8h50m25s
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Failing after 8h50m27s
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Failing after 8h50m27s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Failing after 8h50m27s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 8h50m22s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 8h50m34s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 8h50m39s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 8h39m44s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 8h50m22s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 8h50m34s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 9h26m5s
de56a67457

🚀 预览环境已部署

项目 详情
PR号 #1946
预览链接 https://pr-1946.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1946 | | 预览链接 | [https://pr-1946.preview.xiaoxiajianji.com](https://pr-1946.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia merged commit 1bf0e73fd2 into develop 2026-09-16 06:52:20 +08:00
xiaoxia reviewed 2026-09-16 06:52:36 +08:00
xiaoxia left a comment
Author
Owner

ci green, auto-merge via admin (rerun skipped pr-automation)

ci green, auto-merge via admin (rerun skipped pr-automation)

🗑️ 预览环境已清理

PR #1946 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1946 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.