Docker 默认 stop 超时为10秒,但业务如数据库、消息队列等需更长时间完成优雅停机,故需自定义超时;可通过 docker stop -t、docker-compose stop_grace_period 或运行时参数设置,同时应用须正确响应 SIGTERM。

默认情况下,Docker 在执行 docker stop 时会先发送 SIGTERM 信号给容器主进程,等待 10 秒后若进程未退出,再发送 SIGKILL 强制终止。这 10 秒可能不足以让业务完成数据落盘、连接关闭、事务提交等关键操作,导致数据丢失或状态不一致。
为什么需要自定义超时时间
很多服务(如数据库、消息队列、Web 应用)在收到终止信号后需要做清理工作:
- MySQL / PostgreSQL 需刷写 WAL 日志、关闭连接池、同步脏页
- Kafka Broker 要完成分区重平衡、提交 offset、关闭网络连接
- Spring Boot 应用需触发
@PreDestroy、清空缓存、关闭线程池、提交未完成事务
硬性 10 秒倒计时无法适配不同业务的优雅停机耗时,必须按实际需求调整。
设置超时时间的几种方式
1. 命令行临时指定
使用 -t 或 --time 参数:
docker stop -t 30 my-app-container
该命令将等待最多 30 秒才强制杀掉容器,适用于调试或手动维护场景。
2. Docker Compose 中配置
在 docker-compose.yml 的服务定义中添加 stop_grace_period:
services:
app:
image: my-web-app
stop_grace_period: 45s
该值支持 s(秒)、m(分)单位,如 2m 表示 120 秒。Compose 启动/停止时自动生效。
3. Dockerfile 中声明(仅影响 build 时默认值,不强制运行时)
可在 Dockerfile 中设置 STOPSIGNAL 和建议的等待时间(但实际仍由运行时参数决定):
STOPSIGNAL SIGTERM
注意:STOPSIGNAL 只改信号类型,不设超时;超时必须由 docker run 或 docker-compose 指定。
配合应用层实现真正优雅停机
光调长超时没用,容器内进程必须响应 SIGTERM 并主动完成清理:
- Java 应用:注册 JVM Shutdown Hook 或监听 Spring 的
ContextClosedEvent - Node.js:监听
process.on('SIGTERM', ...),关闭 HTTP server 后再process.exit(0) - Golang:用
signal.Notify捕获syscall.SIGTERM,执行 defer 清理逻辑 - 确保主进程是 PID 1(避免被 init 系统接管导致信号丢失),必要时用
tini或--init
验证是否生效的小技巧
可临时在容器启动命令中加入日志输出,观察从 SIGTERM 到进程退出的实际耗时:
docker run --rm -t \ --stop-timeout 60 \ -e "LOG_SIGTERM=true" \ nginx:alpine
再配合 docker stop -t 60 + docker logs 查看日志时间戳,确认清理逻辑是否跑完。










