gitlab的on_stop仅触发销毁作业,真正“秒级物理擦除”依赖teardown-sandbox.sh直连基础设施api执行幂等清理(如kubectl delete ns、docker stack rm),需环境显式声明、on_stop作业正确配置、并借助auto_stop_in或gitlab api在分支合并后主动调用停止。

on_stop 本身不负责“物理擦除”,它只负责触发一个预定义的作业。所谓“秒级物理擦除虚拟沙箱”,实际是靠你写的 on_stop 作业去调用销毁逻辑(如清理容器、释放云资源、删除 K8s Namespace、卸载 LVM 卷等),而 on_stop 是让这个销毁动作被 GitLab 环境生命周期自动调度的关键开关。
要真正实现“特性分支合并后自动秒级擦除”,需满足三个条件:环境可识别、销毁动作可执行、触发时机可控。下面是关键实操要点:
环境必须显式声明且绑定到分支
在部署作业中使用environment:name+url,并配合environment:when:manual或默认on_success;同时用environment:automatic_url或变量确保每个特性分支有唯一环境名(例如staging/$CI_COMMIT_REF_SLUG)。GitLab 才能区分这是哪个分支的沙箱。-
on_stop作业必须存在、同环境、且带action: stopdeploy-to-sandbox: stage: deploy script: ./deploy-sandbox.sh environment: name: staging/$CI_COMMIT_REF_SLUG url: https://$CI_COMMIT_REF_SLUG.staging.example.com on_stop: teardown-sandbox only: - /^feature\/.*$/ teardown-sandbox: stage: cleanup script: ./teardown-sandbox.sh when: manual # 注意:on_stop 触发时会自动转为 manual → auto,无需改 environment: name: staging/$CI_COMMIT_REF_SLUG action: stop # 必须写!否则 GitLab 不认这是停止作业 variables: GIT_STRATEGY: none # 避免拉代码开销,秒级关键 -
擦除逻辑必须无依赖、幂等、超快
teardown-sandbox.sh应直连基础设施 API,跳过 Git 拉取、包安装等环节。例如:- Docker:
docker stack rm $CI_COMMIT_REF_SLUG || true - Kubernetes:
kubectl delete ns $CI_COMMIT_REF_SLUG --grace-period=0 --force 2>/dev/null || true - 云平台:调用 Terraform Destroy 的轻量 wrapper,或直接调用云 CLI 删除 Resource Group / Tagged Instances
- Docker:
-
自动触发靠“环境自动移除”或“UI 手动操作”,不是靠合并事件本身
GitLab 不会因为“分支被合并”就自动删环境——除非你:- 设置
auto_stop_in: 1 hour,让环境过期后自动触发on_stop(适合定时回收); - 或在合并 MR 后,由另一个流水线(如
merge-trigger)调用 GitLab API 主动关闭该环境:curl -X POST "$CI_API_V4_URL/projects/$CI_PROJECT_ID/environments/$ENV_ID/stop" --header "PRIVATE-TOKEN: $GITLAB_TOKEN"
其中$ENV_ID可从上一次部署作业的CI_ENVIRONMENT_ID获取并存为 artifact 或变量。
- 设置
真正“秒级”的核心不在 GitLab,而在你的 teardown-sandbox.sh 是否足够薄、够快、够直接。GitLab on_stop 只是那个可靠的、带上下文(环境名、变量、权限)的“按下删除键”的机制。











