退出码137表明容器被OOM Killer强制终止,需禁用自动重启策略暴露根因;查dmesg确认“Killed process”及anon-rss值,结合free -h和df -h排查宿主机内存与磁盘瓶颈。
直接看退出码,再禁用自动重启,才能暴露真实问题。容器反复拉起又崩溃,本身就会吃光 cpu、内存和磁盘 i/o,但根源往往藏在第一次失败里。
先查退出码,锁定终止类型
退出码是第一线索,它告诉你容器为什么停:
- 137:几乎肯定是被内核 OOM Killer 杀掉的(SIGKILL),不是应用自己退出。别只信容器 memory limit,得看宿主机真实内存水位
- 143:收到 SIGTERM 后没及时退出,常见于健康检查失败、应用未处理信号、或响应慢卡死
- 1 或其他非零值:启动阶段就崩了,比如配置缺失、数据库连不上、权限拒绝、命令找不到(127)、入口脚本异常(255)
执行:docker inspect 容器名 | grep -A 5 "State",重点关注 ExitCode 和 OOMKilled 字段。注意:OOMKilled: false 不代表没被 OOM 杀,必须结合内核日志验证。
禁用 restart 策略,让错误“停下来”
只要 restart: always 或 unless-stopped 开着,容器一崩就立刻重试,掩盖原始现场。临时关掉它,才能看清第一次失败时发生了什么:
- Docker Compose:注释掉服务下的
restart行,然后docker-compose down && docker-compose up - Docker CLI:删掉
--restart参数,重新docker run
此时容器会卡在 Exited (X) 状态,你就能安全查日志、进容器调试、甚至用 docker exec -it 容器名 sh 检查运行时环境。
查内核日志确认是否真被 OOM 杀
Docker inspect 的 OOMKilled 字段有时不准。必须看真实内核记录:
- 运行:
dmesg -T | grep -i "killed process" - 如果输出中出现
Killed process XXX (your-container-name) ... Out of memory,就是铁证 - 重点看
anon-rss值(单位 kB),它反映进程实际占用的物理内存,比容器 limit 更真实
盯住宿主机整体资源,别只盯容器
容器频繁重启常是结果,不是原因。系统级瓶颈才是根因:
-
free -h:看available列,长期低于 500MB 就说明内存已吃紧;同时留意swap是否跑满 -
df -h:检查/var/lib/docker所在分区,满会导致无法写日志、无法创建镜像层,间接引发异常退出 -
docker stats --no-stream:找出长期高 CPU(>80%)或内存持续上涨的“嫌疑容器”,它们可能是循环重启的源头


















