ENTRYPOINT ['/app/server', '-c', '/etc/app.conf'] # 需要 shell 时末尾补 exec CMD exec /app/server -c /etc/app.conf docker stop -t 30 app
每次 docker stop 都要等满默认的 10 秒才结束,应用日志里找不到任何优雅停机的记录,退出码固定是 143,像是被直接掐断。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,shell 形式的 ENTRYPOINT 会包一层 /bin/sh -c,PID 1 变成 shell,SIGTERM 发给 shell 就停了,后面的应用进程根本收不到信号,只能等超时被强杀,停机逻辑等于没写,改一行就能验证。
「容器信号传递」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。
验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。
处理上按这个顺序:把入口改成 exec 形式的 JSON 数组 不要再写成字符串 也不加 sh -c;确实要用 shell 就在命令前面加 exec 把进程替换掉 否则等于白改;停一次容器看日志里有没有走出来停机流程 没有就是信号没到。
改完只确认一件事:docker stop 两秒内返回,日志里能看到应用打印的停机完成,连接也关干净。
