关键在于主进程捕获SIGTERM执行清理,配合Docker的stop-signal配置与足够长的stop-grace-period,确保数据落盘完成后再终止。
要在 docker 中让容器在退出前完成业务数据的最后保存,关键不是“配置退出信号”,而是让容器主进程能正确捕获 sigterm 并执行清理逻辑,同时配合 docker 的停止机制。这是一套协同动作,缺一不可。
确保应用主动监听 SIGTERM
容器内运行的主进程(比如你的 Java 服务、Node.js 应用或 Python 脚本)必须显式注册 SIGTERM 处理函数。不能依赖默认行为(直接退出),否则没机会做保存。
- 例如在 Node.js 中: process.on('SIGTERM', () => { saveDataToDisk(); cleanupConnections(); process.exit(0); });
- Python 示例: import signal; def handle_exit(*_): save_and_flush(); exit(0); signal.signal(signal.SIGTERM, handle_exit)
- Java 程序需通过
Runtime.getRuntime().addShutdownHook()注册钩子
告诉 Docker 该发哪个信号
Docker 默认发送 SIGTERM,但如果你的应用监听的是其他信号(如 SIGHUP),就需要显式声明:
- 在
Dockerfile中添加:
STOPSIGNAL SIGUSR1 - 或在
docker run时指定:
docker run --stop-signal SIGUSR1 ... - Compose 文件中写:
stop_signal: "SIGUSR1"
给足时间完成保存操作
Docker 发送 SIGTERM 后,默认只等 10 秒就发 SIGKILL 强制终止。若你的数据落盘、事务提交、连接关闭耗时较长,必须延长这个等待窗口:
- 命令行启动时:
docker stop -t 60 my_container(等 60 秒) - Compose 中设置:
stop_grace_period: 60s - 注意:这个超时值必须大于你应用实际保存所需的最大耗时,否则仍会被 SIGKILL 中断
验证是否真正生效
光写代码和配参数不够,得实测确认流程走通:
- 启动容器后,手动执行:
docker kill -s SIGTERM my_container,观察日志里是否有“开始保存”“保存完成”等输出 - 再试
docker stop,看是否按预期延迟退出,而不是瞬间消失 - 检查宿主机上目标路径(如挂载的 volume 或 host path)中,数据文件是否真实写入且内容完整


















