欢迎光临
我们一直在努力

Docker 容器一直重启怎么办?Restarting 状态排查教程

1. Docker 容器为什么会一直 Restarting?

在 Linux 服务器上运行 Docker 项目时,有时执行:

docker ps

会发现某个容器的状态一直是:

Restarting (1) 8 seconds ago

过几秒以后再次执行,仍然显示 Restarting。

这种情况通常意味着:

容器已经启动,但内部程序很快退出,随后又被 Docker 的重启策略重新拉起。

于是就形成:

启动 → 程序退出 → Docker 重启 → 再次退出 → 再次重启

的循环。

常见原因包括:

配置文件错误;

环境变量缺失;

数据库无法连接;

端口冲突;

Volume 文件权限异常;

程序依赖缺失;

启动命令错误;

服务器内存不足;

程序本身启动失败。

因此遇到 Restarting 时,不建议第一时间反复执行 docker restart,而应该先找到容器为什么退出。

2. 先确认哪个容器正在重启

Docker容器Restarting状态排查

执行:

docker ps -a

例如:

CONTAINER   IMAGE        STATUS                         PORTS
web-app     app:latest   Restarting (1) 8 seconds ago
mysql       mysql:8      Up 3 hours                     3306/tcp

这里可以看到:

web-app

正在反复重启,而 MySQL 正常运行。

如果项目使用 Docker Compose,也可以执行:

docker compose ps

先确定出问题的是哪个服务,再继续排查。

3. 第一件事:查看容器日志

Docker查看容器启动错误日志

多数 Docker Restarting 问题,都可以先从日志中找到线索。

执行:

docker logs --tail 100 容器名称

例如:

docker logs --tail 100 web-app

如果容器重启非常频繁,也可以只查看最近几分钟:

docker logs --since 10m web-app

常见错误可能包括:

Permission denied
Connection refused
Address already in use
No such file or directory
Missing environment variable

或者数据库、Redis、API 等连接失败信息。

如果日志一直重复同一个错误,基本就已经找到排查方向。

4. 查看容器退出码 ExitCode

如果日志没有明显信息,可以继续查看容器退出码。

执行:

docker inspect -f '{{.State.ExitCode}}' 容器名称

例如:

docker inspect -f '{{.State.ExitCode}}' web-app

也可以一次查看更多状态:

docker inspect -f 'Status={{.State.Status}} ExitCode={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}} Error={{.State.Error}}' web-app

常见 ExitCode 可以作为排查参考。

0:程序正常退出。

1:应用程序通用错误。

126:命令存在,但无法执行。

127:启动命令或程序不存在。

137:进程收到 SIGKILL,需要继续检查是否发生 OOM,也可能是其他强制终止原因。

139:程序发生段错误等异常。

143:进程收到 SIGTERM,某些正常停止操作也可能出现。

不要只根据一个 ExitCode 就直接下结论,还需要结合日志和容器状态一起判断。

5. ExitCode 137 要检查是不是内存不足

Docker检查ExitCode和OOMKilled状态

如果容器退出码为:

137

继续检查:

docker inspect -f '{{.State.OOMKilled}}' 容器名称

如果输出:

true

说明这个容器曾经因为内存不足被系统终止。

还可以检查系统日志:

dmesg -T | grep -Ei 'oom|out of memory|killed process'

并查看服务器当前内存:

free -h

如果服务器运行 Docker,也可以查看各容器内存:

docker stats --no-stream

需要注意:

ExitCode 137 并不一定百分之百代表 OOM。

应该结合 OOMKilled 和系统日志确认。

如果确实是内存不足,需要继续检查:

容器是否存在内存泄漏;

Java、MySQL 等程序配置是否过大;

服务器是否运行过多容器;

是否需要优化程序或增加内存。

6. 检查 Docker Compose 配置

如果项目通过 Docker Compose 部署,可以先验证配置:

docker compose config

如果 Compose 文件存在:

缩进错误;

变量解析错误;

格式问题;

配置冲突;

通常会直接提示。

如果命令能够正常输出完整配置,说明 Compose 文件基础语法通常没有明显问题。

还可以查看最终解析后的环境变量和配置,确认是否和预期一致。

7. 检查环境变量是否缺失

很多 Docker 应用需要通过环境变量提供:

数据库地址;

数据库用户名;

数据库密码;

API 地址;

Token;

应用密钥。

例如 Compose 中可能有:

environment:
  DB_HOST: mysql
  DB_USER: app
  DB_PASSWORD: ${DB_PASSWORD}

如果 .env 中没有:

DB_PASSWORD

程序可能启动后立即报错退出。

可以执行:

docker compose config

检查 Compose 最终解析出来的配置。

如果项目使用 .env 文件,也要确认:

.env 文件存在;

文件位置正确;

变量名称正确;

没有多余空格;

敏感参数没有被误删。

不要把真实数据库密码或 Token 发到公开文章、论坛或者截图中。

8. 检查数据库是否无法连接

Web 应用频繁 Restarting,一个很常见的原因就是数据库还没有启动,或者连接信息错误。

先查看所有容器:

docker compose ps

确认数据库服务是否正常。

例如 MySQL:

docker logs --tail 100 mysql

如果应用日志中出现:

Connection refused

或者:

Can't connect to MySQL server

需要继续确认:

数据库容器是否启动;

数据库端口是否正确;

Docker 网络是否正常;

数据库用户名和密码是否正确;

应用使用的是容器服务名还是错误的 IP。

在同一个 Compose 项目中,应用连接 MySQL 时通常应该根据实际配置使用对应服务名称,而不是随意填写 127.0.0.1。

9. 检查端口是否冲突

如果日志中出现:

Address already in use

或者 Docker 启动时提示端口已经被占用,就需要检查宿主机端口。

例如项目需要使用 8080:

ss -lntp | grep 8080

也可以查看当前 Docker 端口:

docker ps

如果已经有另一个容器占用了:

0.0.0.0:8080

新的容器就无法继续使用相同的宿主机端口。

可以修改 Compose:

ports:
  - "8081:80"

然后重新创建:

docker compose up -d

如果遇到的是服务器端口无法访问,而不是容器 Restarting,可以参考:

相关阅读: 云服务器端口不通怎么办?Connection refused 与 timed out 排查教程

10. 检查 Volume 文件权限

有些容器需要读写宿主机目录。

例如:

volumes:
  - ./data:/app/data

如果宿主机上的 ./data 权限不正确,应用启动时可能出现:

Permission denied

首先查看目录:

ls -lah

再查看具体数据目录:

ls -ld ./data

不要看到权限问题以后就直接使用:

chmod -R 777

作为长期解决方案。

更合理的方法是先确认:

容器内部程序使用哪个 UID/GID;

宿主机目录当前属于哪个用户;

项目官方要求什么权限。

再针对性修改所有者和权限。

11. 检查文件或配置挂载是否错误

例如 Compose 配置:

volumes:
  - ./config.yml:/app/config.yml

如果服务器上:

config.yml

不存在;

文件名写错;

路径错误;

配置内容格式错误;

应用也可能启动失败。

可以执行:

docker inspect 容器名称

查看容器实际挂载情况。

也可以:

docker inspect -f '{{json .Mounts}}' 容器名称

确认宿主机目录和容器目录是否符合预期。

12. 检查启动命令是否正确

如果 Dockerfile 或 Compose 覆盖了容器启动命令,也可能导致容器立即退出。

例如:

command: ./start.sh

但容器内没有:

./start.sh

就可能启动失败。

如果日志中出现:

command not found

或者:

No such file or directory

就应该重点检查:

command

entrypoint

脚本路径;

脚本执行权限;

镜像内部实际文件。

13. Restart Policy 为什么会导致一直重启?

Compose 中常见:

restart: unless-stopped

或者:

restart: always

这些配置本身并不是故障。

它们的作用是:

当容器异常退出后,让 Docker 尝试重新启动容器。

真正的问题还是容器内部程序为什么会退出。

如果没有重启策略,程序启动失败后可能只是显示:

Exited (1)

配置了自动重启以后,就会变成不断:

Restarting

所以不要只删除 restart 就认为问题解决了。

应该找到应用退出的真正原因。

14. 如何临时停止 Restarting 循环?

如果容器反复重启影响排查,可以临时关闭自动重启策略。

例如:

docker update --restart=no 容器名称

然后停止:

docker stop 容器名称

这样可以避免容器不停启动。

如果使用 Docker Compose,更推荐最终修改 Compose 中的:

restart: "no"

或者暂时移除 restart 配置。

排查并解决问题以后,再恢复原来的重启策略,并重新创建容器。

15. 查看容器重启次数

可以执行:

docker inspect -f '{{.RestartCount}}' 容器名称

例如:

128

说明这个容器已经自动重启了 128 次。

如果短时间内 RestartCount 持续快速增加,说明问题仍然没有解决。

修改配置后,可以重新创建容器:

docker compose up -d --force-recreate

然后再次观察状态。

16. 修改配置后重新部署

处理完配置以后,可以先验证:

docker compose config

确认没有问题以后:

docker compose up -d

如果需要确保容器重新创建:

docker compose up -d --force-recreate

查看状态:

docker compose ps

再观察日志:

docker compose logs --tail 100

如果状态从:

Restarting

变成:

Up

并且日志不再出现启动错误,说明问题基本已经解决。

17. 容器显示 unhealthy 和 Restarting 一样吗?

不一样。

Restarting

通常表示容器中的主进程已经退出,Docker 正在重新启动。

而:

unhealthy

通常表示容器仍在运行,但 Healthcheck 检测没有通过。

例如:

应用虽然启动;

但 HTTP 接口访问失败;

数据库未准备好;

Healthcheck 命令返回错误。

因此遇到 unhealthy 时,应该重点检查:

docker inspect 容器名称

中的 Health 信息以及应用本身状态,而不是完全按照 Restarting 的方式处理。

18. Docker 容器重启快速排查顺序

建议按照下面的顺序排查:

第一步:确认 Restarting 容器

docker ps -a

第二步:查看日志

docker logs --tail 100 容器名称

第三步:查看 ExitCode

docker inspect -f '{{.State.ExitCode}}' 容器名称

第四步:检查是否 OOM

docker inspect -f '{{.State.OOMKilled}}' 容器名称

第五步:验证 Compose

docker compose config

第六步:继续检查

环境变量;

数据库;

端口;

Volume 权限;

配置文件;

启动命令。

最后修复问题以后:

docker compose up -d --force-recreate

再次确认运行状态。

19. 不建议直接删除容器解决问题

如果容器一直重启,不建议什么都没检查就直接执行:

docker rm -f 容器名称

因为删除以后,如果 Compose 配置本身仍然存在错误,新创建的容器还是会继续重启。

而且部分业务如果没有正确持久化数据,还可能产生数据风险。

正确顺序应该是:

查看日志 → 确认退出原因 → 修改配置 → 重新创建 → 检查运行状态

而不是不断删除容器。

20. 服务器配置不足也可能导致频繁重启

如果一台服务器同时运行大量 Docker 应用,内存或者 CPU 已经不足,也可能导致部分容器异常。

可以检查:

free -h
docker stats --no-stream
df -h

除了内存之外,还要注意磁盘空间。

如果磁盘已经达到 100%,应用也可能因为无法创建文件、写入数据库或保存日志而退出。

如果需要搭建 Docker 项目,可以根据实际项目规模选择莱卡云 Linux 云服务器。

查看官网购买链接: https://www.lcayun.com

服务器还没有安装 Docker 的话,可以参考:

安装教程: 服务器上安装docker和docker-compose教程

21. 总结

Docker 容器一直显示 Restarting,本质上通常不是“Docker 不停重启容器”这么简单。

真正需要找到的是:

容器内部程序为什么退出。

首先执行:

docker ps -a

找到异常容器。

然后查看:

docker logs --tail 100 容器名称

再检查:

docker inspect -f '{{.State.ExitCode}}' 容器名称

如果 ExitCode 为 137 等异常值,还可以继续检查:

docker inspect -f '{{.State.OOMKilled}}' 容器名称

之后再根据日志分别排查:

环境变量;

数据库连接;

端口冲突;

Volume 权限;

配置文件;

启动命令;

服务器内存和磁盘。

找到真正原因并修复以后,再重新创建容器,通常才能彻底解决 Restarting 循环。

赞(0)
未经允许不得转载:莱卡云 » Docker 容器一直重启怎么办?Restarting 状态排查教程