docker events监听die事件是最可靠异常退出信号源,需结合exitCode、OOMKilled、Error字段及日志、资源指标快速定位根因。
容器异常退出本身不会主动“发出”事件,必须靠外部系统监听并捕获。docker daemon 提供的 docker events 是最直接、轻量且无需额外组件的方式,适合单机环境快速落地。
用 docker events 实时监听 die 事件
容器因崩溃、OOM、未捕获异常等异常退出时,Docker daemon 会广播 die 类型事件(注意:不是 stop 或 destroy)。这是最可靠的异常退出信号源。
- 运行命令监听:
docker events --filter 'event=die' --format '{{json .}}' - 事件体中包含关键字段:
.Actor.ID(容器ID)、.TimeNano(纳秒时间戳)、.Actor.Attributes.name(容器名),可用于关联后续排查 - 若需补充退出码和原因,可在收到
die事件后立即执行:docker inspect <id> --format='{{.State.ExitCode}} {{.State.OOMKilled}} {{.State.Error}}' - 建议用 systemd 或 supervisor 启动监听脚本,避免中断导致事件丢失
结合容器内 trap 捕获退出前上下文
虽然 trap 无法捕获 kill -9 或 OOMKilled 等强制终止,但对大多数应用级异常退出(如未处理 panic、进程 exit(1))仍有效,可补全日志维度。
- 在自定义 ENTRYPOINT 脚本开头添加:
trap 'echo "$(date -u +%FT%TZ) [EXIT] code=$? signal=$SIG" >> /var/log/exit.log' EXIT - 确保主进程是 PID 1(用
exec "$@"替换 shell),否则信号无法透传到 trap - 日志写入后可通过
docker logs直接查看,无需进入容器
区分异常退出与正常运维操作
仅监听 die 不够——它既包括崩溃,也包括手动 docker stop。需结合其他字段做判断:
- 检查事件中的
.Actor.Attributes.exitCode:非 0 值更倾向异常;0 值多为预期结束(但仍需结合业务逻辑确认) - 比对
.Actor.Attributes.name和标签:启动时加-l role=backend,监听时过滤--filter label=role=backend,缩小关注范围 - 观察是否伴随
oom事件:同一容器 ID 若先出现oom再出现die,基本可判定是内存耗尽 - 注意
die和destroy的时序:若两者紧邻,可能是运维清理,而非运行时异常
退出后快速定位根因的三步动作
捕获到异常退出事件后,别急着重启,先做这三件事:
-
查退出码:运行
docker ps -a | grep <name>看 STATUS 列括号里的数字;137 = OOM,143 = SIGTERM,1 = 应用错误 -
读标准输出:执行
docker logs --tail 200 <container_id>,重点看最后一屏错误堆栈或 panic 信息 -
验资源配额:用
docker stats <container_id>回溯历史峰值,或检查docker inspect中的HostConfig.Memory和实际使用是否接近


















