首页 > Technology > 正文

Docker 容器一直重启或退出怎么办?系统排查指南

fenij 2026-07-28 20 Technology

docker ps 里容器状态一直显示 Restarting (1) xx seconds ago,或者刚 up 没多久又变成 Exited——这是用 Docker 时最常碰到的故障之一。容器反复重启,本质就一句话:容器主进程退出了,而重启策略又把它拉起来,于是循环。排查的思路也很直接,就是去找”主进程到底为什么退出”。下面按步骤给出能直接复制的命令。

第一步:看容器日志,绝大部分问题在这一步就能看出来

docker logs --tail 100 容器名
docker logs -f 容器名   # 实时跟踪重启瞬间的输出

常见的日志线索有这些:配置文件路径写错、数据库连不上、端口被占用、缺环境变量、应用自己抛异常。日志能看懂的,直接回去修应用问题就行;日志为空或者看不出名堂的,继续下一步。

第二步:查退出码,判断退出类型

docker inspect 容器名 --format '{{.State.ExitCode}} {{.State.OOMKilled}} {{.State.Error}}'

退出码对照如下:

  • 0:进程正常结束——通常是容器里没有前台常驻进程(见第四步);
  • 1:应用报错退出——回去细看 docker logs;
  • 137:被 SIGKILL 杀掉,若 OOMKilled 为 true 就是内存超限;
  • 126/127:启动命令不可执行/找不到——检查 entrypoint 和 command 的拼写;
  • 139:段错误,多半是程序或依赖库自己的缺陷。

第三步:内存不足(退出码 137)的处理

先确认宿主机整体内存和容器的限制:

free -h
docker stats --no-stream

如果容器设了 -m 内存上限,而且经常打满,要么调大限制,要么优化应用(比如给 Java 应用设 -Xmx 小于容器限制,给 MySQL 容器调低 innodb_buffer_pool_size)。宿主机整体内存不够时,可以临时加 swap 应急:

fallocate -l 2G /swapfile && chmod 600 /swapfile
mkswap /swapfile && swapon /swapfile

第四步:退出码 0 却一直重启?主进程没有常驻

容器要求 PID 1 是一个前台常驻的进程。下面这些写法都会”启动即退出”:入口命令是一条执行完就结束的脚本、nginx 没加 daemon off、用了 service xxx start 这类后台化命令。修复示例:

# 错误:CMD service nginx start
# 正确:
CMD ["nginx", "-g", "daemon off;"]

调试时可以先用 sleep 把容器保住,再进去手动跑命令看报错:

docker run -it --entrypoint /bin/sh 镜像名
# 容器内手动执行原启动命令,直接观察报错

第五步:检查重启策略与依赖顺序

docker inspect 容器名 --format '{{.HostConfig.RestartPolicy.Name}}'

如果应用依赖数据库,而数据库容器还没就绪应用就启动失败,就会形成”启动-失败-重启”的循环。docker-compose 里应该用 healthcheck + depends_on 的 condition: service_healthy,而不是裸的 depends_on。另外磁盘写满(用 df -h 检查)也会让容器反复起不来。

常见问题

如何暂时阻止容器无限重启,方便排查?
先执行 docker update --restart=no 容器名docker stop,排查修好后再改回 always 或 unless-stopped。

docker logs 什么都没有输出怎么办?
说明主进程在打印任何内容之前就退出了,多半是入口命令本身有误。用上面那个 –entrypoint /bin/sh 的方式进容器,手动执行启动命令来定位。

容器在宿主机重启后全部变成 Exited 正常吗?
如果重启策略是 no 就属于正常现象。希望开机自启的容器,应该设成 –restart unless-stopped。

如果你的容器问题按上面的步骤还没解决,欢迎到 fenij.com 评论区贴出 docker logs 和退出码,我们帮你一起看。