docker stop 是滚动更新或蓝绿部署中优雅终止旧容器的收尾动作,需在新服务就绪、流量切换完成后执行,配合 sigterm、合理超时及健康检查,确保零连接丢弃与数据安全。
在 ci 流水线中用 docker stop 安全下线旧版服务,关键不是“单纯停止”,而是把它嵌入可控、可观察、有兜底的发布流程里。它本身不提供零停机能力,但配合编排策略和前置检查,能避免强制中断、连接丢弃或数据损坏。
明确 docker stop 的角色定位
它负责优雅终止单个容器实例,是滚动更新或蓝绿切换中“收尾动作”的一环。不能跳过健康检查直接 stop,也不能在流量未切走时就执行。
- 发送
SIGTERM,给应用预留清理时间(如关闭数据库连接、刷写缓存、完成正在处理的请求) - 默认等待 10 秒,超时后自动发
SIGKILL—— 这个时间必须与应用实际退出耗时匹配 - 不删除容器,状态变为
Exited,便于日志排查或手动恢复
在 CI 脚本中安全集成 stop 的要点
-
先确认新服务已就绪再触发 stop
- 调用
curl -f http://new-service:8080/health或使用docker container inspect检查.State.Health.Status == "healthy" - 避免“新容器启动了但还没 ready,旧容器已被 stop”的空窗期
- 调用
-
控制 stop 的目标范围,避免误停
- 使用明确的容器名称或标签过滤,例如:
docker stop $(docker ps -q --filter "label=service=api" --filter "status=running")
- 禁止用
docker stop $(docker ps -q)这类无差别命令,尤其在共享构建节点时
- 使用明确的容器名称或标签过滤,例如:
-
设置合理的超时时间,适配业务特性
- Web API 类服务:
-t 15通常足够 - 批处理或长连接服务(如 WebSocket 网关):需设为
-t 60或更高,并在应用内实现优雅关闭逻辑 - 可通过 Compose 的
stop_grace_period统一配置:services: api: image: myapp:v2 stop_grace_period: 45s
- Web API 类服务:
-
stop 后验证旧容器确实退出,且无残留进程
- 检查退出码是否为 0
- 补充校验:
if ! docker ps -f "name=old-api" -q | grep -q .; then echo "✅ Old container stopped cleanly" else echo "❌ Still running — investigate manually" exit 1 fi
和主流部署策略的协作方式
-
滚动更新(推荐用于多数微服务)
-
docker stack deploy或kubectl rollout自动调用 stop,你只需确保update_config.order: start-first+ 合理的parallelism - CI 中无需手写 stop 命令,重点放在镜像推送、配置校验和 post-deploy 健康断言
-
-
蓝绿部署(适合强一致性或数据库迁移场景)
- stop 仅作用于“旧环境”整组容器,且必须在路由切换完成、确认新环境稳定 2–3 分钟后再执行
- 示例流水线片段:
# 切流完成后等待并验证 sleep 120 ./verify-traffic-shift.sh || exit 1 # 安全下线蓝环境 docker-compose -f docker-compose.blue.yml down --timeout 30
-
CI 中慎用的反模式
-
docker kill替代docker stop(丢失优雅关闭机会) - stop 后立刻
docker rm,导致无法查日志 - 在没有负载均衡器或服务发现的情况下直接 stop 主服务容器
-
不复杂但容易忽略:stop 是“刹车”,不是“熄火开关”。真正决定是否安全的,是它前面的就绪判断和后面的流量接管。











