docker stop 是优雅停止的标准方式,它先发送 sigterm 信号给 pid 1 进程,等待默认 10 秒让应用执行清理;超时未退出则补发 sigkill 强制终止,可通过 --time 参数或 stop_grace_period 配置调整等待时间,并需应用主动监听 sigterm 才能真正实现优雅关闭。

直接用 docker stop 就是优雅停止的标准方式,关键在于理解它背后的行为逻辑和配合应用的正确响应。
stop 默认就是优雅的:先发 SIGTERM,再等 10 秒
执行 docker stop my-container 时,Docker 不会立刻杀进程。它会向容器内 PID 1 进程发送 SIGTERM(信号 15),然后默认等待 10 秒。这段时间里,你的应用如果捕获了这个信号,就能执行关闭前的清理动作——比如关监听端口、刷缓存、提交事务、注销服务发现等。
- 超时前正常退出 → 容器状态变为
exited,整个过程安静完成 - 超时后仍未退出 → Docker 自动补发 SIGKILL(信号 9),强制终止,此时无清理机会
根据应用实际需要调整等待时间
10 秒是默认值,但不是万能值。比如一个正在写入大文件或处理长事务的服务,可能需要更久才能安全收尾。
- 临时延长:加
--time参数,例如docker stop --time=30 my-container(等 30 秒) - 长期生效:在
docker run中指定,如docker run -d --stop-timeout=30 nginx - Compose 场景:在
docker-compose.yml里配置stop_grace_period: 30s
确保你的应用真能响应 SIGTERM
命令再规范,应用不接信号也白搭。常见问题包括:
- 用 shell 脚本启动主程序(如
CMD ./start.sh),导致 SIGTERM 被 shell 拦截,没传给真正干活的进程 - Go/Java/Node 等程序没写信号监听逻辑,收到 TERM 就当没听见
- 主进程不是 PID 1(比如被 wrapper 包了一层),信号无法送达
解决办法:用 exec 启动主进程(如 CMD exec python app.py),并在代码中显式监听 SIGTERM。
批量停止也要守住优雅底线
想一次停多个?可以,但别跳过语义:
- 停所有运行中容器:
docker stop $(docker ps -q) - 按名字模式停:
docker stop $(docker ps -q --filter "name=api-") - 加超时更稳妥:
docker stop --time=20 $(docker ps -q)
注意:避免混用 docker kill(直发 SIGKILL),除非确认必须强杀且可接受数据风险。











