stopsignal 指令用于指定容器停止时向 pid 1 进程发送的信号,默认 sigterm;需在 dockerfile 中 cmd/entrypoint 前设置,且应用必须实际处理该信号才能实现优雅退出。

STOPSIGNAL 指令用于指定容器停止时向主进程发送的系统信号,默认是 SIGTERM。合理设置它,能让应用优雅关闭、释放资源、保存状态,避免数据丢失或连接中断。
STOPSIGNAL 的作用和常见取值
当执行 docker stop 时,Docker 默认向 PID 1 进程发送 SIGTERM;若超时(默认 10 秒),再发 SIGKILL 强制终止。STOPSIGNAL 允许你显式声明希望接收的信号,比如:
- SIGTERM(数值 15):标准终止信号,适合大多数支持优雅关闭的应用(如 Nginx、Node.js)
- SIGQUIT(数值 3):常用于触发 Java 应用的线程 dump 或 Go 程序的 panic 堆栈
- SIGUSR2(数值 12):Nginx reload 配置常用,也可自定义为“热重启”信号
- SIGHUP(数值 1):传统上用于重载配置(如 Apache、Postfix)
在 Dockerfile 中正确使用 STOPSIGNAL
必须放在 Dockerfile 中 CMD 或 ENTRYPOINT 之前生效,且只影响容器主进程(PID 1)。写法简单,但需匹配应用实际处理的信号:
- 用信号名更可读:
STOPSIGNAL SIGTERM - 用数字更明确:
STOPSIGNAL 15 - 若应用只响应 SIGUSR1,则写
STOPSIGNAL SIGUSR1,否则docker stop发出的 SIGTERM 将被忽略 - 不建议设为 SIGKILL(9),因为它无法被捕获或处理,会跳过所有清理逻辑
配合应用代码实现优雅退出
STOPSIGNAL 只是“发什么”,关键还得应用能“接住并处理”。例如 Node.js 服务:
- 监听
process.on('SIGTERM', () => { cleanup(); process.exit(0); }) - 确保数据库连接、文件句柄、HTTP server.close() 都在回调中执行
- 避免在信号处理中调用异步阻塞操作(如未 await 的 Promise),否则可能超时被 kill
- 测试方式:
docker run -d --name test-app your-image,然后docker stop test-app并观察日志是否输出 “shutting down…”
验证与调试技巧
确认 STOPSIGNAL 是否生效,不能只看 Dockerfile 写了没,还要验证运行时行为:
- 启动容器后,进入:
docker exec -it container-id sh,执行cat /proc/1/status | grep SigQ(部分镜像需 procps 工具) - 更直接方式:
docker inspect container-id --format='{{.HostConfig.StopSignal}}',输出应为设定的信号名或数字 - 手动测试信号:
docker kill -s SIGUSR2 container-id,观察应用日志是否响应 - 注意:如果用了
supervisord或tini作为 init,确保它们转发信号给子进程,否则 PID 1 不是你的应用,STOPSIGNAL 无效











