Docker 容器启动后秒退?按退出码 0/1/125/126/127/137/139/143 逐个排查

0 阅读3分钟

CI 显示部署成功,几秒后 docker ps -a 却是 Exited (1)、Exited (137),或者一直在 Restarting。先别急着加内存、改 restart policy 或删容器重建——容器停下时已经留了线索:退出码。顺序是:拿退出码 → 对照速查表 → 只看一小段日志找第一条异常。

以下命令都只查看、不改动容器,把 YOUR_CONTAINER 换成实际容器名。

1. 拿到退出码

docker ps -a --format 'table {{.Names}}\t{{.Status}}'
docker inspect --format '{{.State.ExitCode}} oom={{.State.OOMKilled}} err={{.State.Error}} started={{.State.StartedAt}} finished={{.State.FinishedAt}}' YOUR_CONTAINER
  • Restarting (1) 括号里是上一次退出的退出码。
  • err 只在 Docker 自己没能启动进程时才有内容,应用崩溃时通常为空,空不代表正常。
  • started 和 finished 只差几秒就是「秒退」;这两个时间是 UTC。

2. 退出码速查

退出码通常含义先查什么
0主进程正常结束Web 服务以 0 退出,多半是进程跑到了后台,或启动命令是一次性任务
1应用自己报错日志里的第一条异常;对照这次改了什么(tag、环境变量、配置)
125Docker 拒绝启动docker run / compose up 的报错:参数、拉镜像、端口被占
126命令执行不了启动命令、文件权限(bind mount 沿用宿主机权限)
127找不到命令程序是否在镜像里、在 PATH 上;精简基础镜像常见
137SIGKILL(128+9)oom= 是否为 true;不是的话查谁发的 kill
139SIGSEGV(128+11)内核日志里的 segfault;是否升级了原生依赖或基础镜像
143SIGTERM(128+15)谁让它停的:重新部署、docker stop、宿主机关机

大于 128 的一般是「被信号(退出码 − 128)终止」,bash 里 kill -l 137 会输出 KILL。137 不等于内存不够:

docker events --since 1h --filter container=YOUR_CONTAINER
sudo dmesg -T | grep -i -E 'out of memory|killed process|segfault' | tail -n 20

events 里先 signal=15、约 10 秒后 signal=9 再 die,是停止时忽略了 SIGTERM 被强杀,不是 OOM——常见于 shell 形式的 CMD,信号没传到你的进程。

0、126、127 先看容器到底在运行什么,以及镜像架构和宿主机是否一致:

docker inspect --format 'entrypoint={{json .Config.Entrypoint}} cmd={{json .Config.Cmd}}' YOUR_CONTAINER
docker image inspect --format '{{.Os}}/{{.Architecture}}' YOUR_IMAGE; uname -m

3. 只看一小段日志

docker logs --since 30m --timestamps YOUR_CONTAINER 2>&1 | head -n 80
  • 停止的容器也能看日志;2>&1 别省,报错多在 stderr。
  • 看部署后的第一条异常,而不是最后一行。
  • 常见第一条:connection refused(容器里的 localhost 是容器自己)、permission denied(挂载目录属主)、文件明明存在却 no such file or directory(脚本带 CRLF 换行)、exec format error(镜像架构和宿主机不一致)。

说明性示例(不是真实客户案例):换成更精简的基础镜像后,容器显示 Restarting (127),inspect 输出 127 oom=false,日志第一行是 exec: gunicorn: not found——入口脚本跑了,但新镜像里没有应用服务器。这时加内存、改重启策略都没用,该回滚 tag 或重新构建时装上依赖。

退出码只是线索,结论要有退出码、日志和对得上的时间。回滚镜像、改 Compose 或内存上限之前,先准备好回退办法。


文中命令都可以直接手敲。我们在做的 OpsMate(itops.sh)把 SSH 终端和 AI 放在同一页:AI 以排查为主,危险命令会被拦截,重启、日志轮转这类低风险处置默认会自动执行。点「需要分析」后命令输出会发到云端 AI。桌面客户端已开源:github.com/vincent-lxc… 。试用有问题或建议,欢迎提 GitHub Issues(github.com/vincent-lxc… Telegram 反馈群(t.me/itopsgroup)…

完整版和中英对照见 OpsMate(itops.sh)指南:www.itops.sh/guides/dock…