售前咨询400-838-0503

Docker容器一直重启怎么办?

发布:2026-10-21 13:07

搜索全部帮助分类的文档

使用Docker部署网站、数据库或其他应用时,可能遇到容器刚启动就退出,随后再次启动,始终无法正常提供服务的情况。

容器反复重启,通常需要分别检查两个问题:程序为什么退出,以及退出后由谁重新启动。 单纯增加重启次数,不能修复配置缺失、内存不足或依赖连接失败。

本文以Linux Docker Engine和Docker Compose为例。Docker命令中的web表示容器名称,Compose命令中的web表示服务名称,两者可能不同,请按实际情况替换。

1. 查看容器状态和重启次数

Docker查看容器Restarting状态、重启次数与退出码

首先列出全部容器,包括已经退出的容器:

docker ps -a --format 'table {{.Names}}\t{{.Status}}'

常见状态可以这样理解:

状态 含义
Up 容器主进程正在运行,不代表业务一定正常
Restarting 容器处于自动重启流程中
Exited 容器主进程已经退出
Created 容器已创建,但尚未成功进入运行状态
Up ... (unhealthy) 主进程仍在运行,但健康检查没有通过

查看目标容器的重启次数和退出码:

docker inspect --format '{{.RestartCount}}' web
docker inspect --format '{{.State.ExitCode}}' web

隔一段时间再次查看,判断重启次数是否仍在增加。

RestartCount属于当前容器,不能当作完整的历史审计记录。容器被删除并重新创建后,不能继续用新容器的计数判断旧容器发生过什么。

2. 查看启动失败前的日志

使用docker logs查看容器启动失败与配置缺失日志

执行:

docker logs --since 10m --tail 80 web

需要时间戳时,可以增加--timestamps:

docker logs --since 10m --tail 80 --timestamps web

重点寻找每次退出前重复出现的错误,例如:

  • 缺少必要配置或环境变量。

  • 数据库认证失败。

  • 文件不存在或权限不足。

  • 配置文件语法错误。

  • 程序运行依赖缺失。

  • 数据目录版本不兼容。

例如,日志持续提示缺少某个数据库连接配置,应先根据应用文档补齐对应配置,而不是继续重启容器。

docker logs主要读取应用输出到标准输出、标准错误的日志。应用把日志写入文件,或者使用了其他日志收集方式时,还需要查看对应日志位置。

没有日志,不代表没有错误。也可以检查Docker记录的状态错误:

docker inspect --format '{{.State.Error}}' web

3. 根据退出码缩小排查范围

退出码可以提供线索,但不能单独确定原因。

退出码 常见含义 排查方向
0 程序正常结束 是否本来就是一次性任务,启动命令是否提前结束
1 程序报告错误 查看应用日志和配置
137 通常对应被SIGKILL终止 检查OOM、人工强制停止或停止超时
143 通常对应SIGTERM终止 检查部署、停止操作和外部管理程序
其他非零值 由程序或运行环境定义 对照应用文档与日志分析

退出码137不一定意味着内存不足。 强制结束进程,或者容器在停止等待超时后被强制终止,也可能出现137。

如果退出码为0,但容器仍然反复启动,应检查:

  • 是否给一次性初始化任务配置了持续重启策略。

  • 启动脚本是否把服务放到后台后自行退出。

  • 是否覆盖了镜像原本的启动命令。

对于需要持续运行的服务,应让实际服务进程以前台方式运行。添加一个无关的保活命令,并不能证明业务已经恢复。

4. 检查是否发生OOM或内存限制过低

执行:

docker inspect --format '{{.State.OOMKilled}}' web
docker inspect --format '{{.HostConfig.Memory}}' web

其中:

  • OOMKilled用于查看容器状态中记录的OOM标记。

  • Memory表示配置的容器内存上限,单位为字节。

  • Memory为0表示没有通过该字段设置内存硬限制,不代表宿主机资源无限。

查看宿主机内存和容器当前占用:

free -h
docker stats --no-stream web

如果容器启动后很快退出,单次docker stats可能无法捕获退出前的内存峰值。

进一步检查内核日志:

sudo journalctl -k -b --since "-30m" --no-pager

查找与故障时间对应的OOM、进程被终止或内存控制组相关记录。

OOMKilled不是完整的历史记录。容器已经重启时,当前显示false不能排除之前发生过OOM,需要结合日志和事件判断。

确认内存不足后,应评估应用实际需求、容器限额和宿主机剩余资源。可以调整并发、缓存或堆内存配置,必要时增加资源,不宜直接取消所有限制。

5. 检查启动命令、挂载目录和依赖服务

查看容器配置的入口、参数和运行用户:

docker inspect --format \
  'Entrypoint={{json .Config.Entrypoint}} Cmd={{json .Config.Cmd}} User={{json .Config.User}}' web

查看挂载信息:

docker inspect --format '{{json .Mounts}}' web

重点检查以下项目:

检查项目 常见问题
启动命令 覆盖了镜像默认命令,参数或路径错误
配置文件 文件不存在、格式错误,或与当前版本不兼容
挂载目录 宿主机路径错误,挂载覆盖了镜像中的必要文件
文件权限 容器运行用户无法读取配置或写入数据目录
数据库、Redis等依赖 地址、凭据、网络或就绪状态异常
存储空间 空间或inode耗尽,导致初始化和日志写入失败

可以同时检查:

df -h
df -i

在普通桥接网络的容器中,127.0.0.1指向容器自身。数据库位于另一个容器时,通常应使用共同网络中的服务名称及容器内部端口。

使用Compose时,还要区分“已经启动”和“已经可以处理请求”。普通启动顺序不能保证数据库已经就绪;需要等待依赖健康时,应为依赖服务配置有效的健康检查,并使用condition: service_healthy。

应用本身也应具备合理的连接重试能力,以应对依赖服务运行期间的短暂中断。

6. 判断是谁在重新启动容器

查看Docker重启策略:

docker inspect --format '{{json .HostConfig.RestartPolicy}}' web

常见策略如下:

策略 主要行为
no 不因主进程退出而自动重启
on-failure 主进程以非零退出码结束时重启,可设置重试次数
always 主进程退出后通常自动重启;手动停止有例外规则
unless-stopped 自动恢复运行,但保留手动停止状态

重启策略只决定退出后的处理方式,不会修复程序本身。

如果策略是no,容器仍被反复拉起,还应检查:

  • 服务器管理面板。

  • systemd服务或定时任务。

  • 自动部署和更新程序。

  • 外部健康监控工具。

  • Swarm、Kubernetes等编排系统。

可以查看近期Docker事件:

docker events --since 30m --until "$(date -Iseconds)" \
  --filter container=web

关注die、start、kill、oom、destroy和create等事件。

Docker事件历史有保留数量限制,不能代替长期审计。如果容器ID反复变化,可能发生的是容器重建,而不是同一个容器不断重启。

7. 如何临时停止重启循环?

Docker临时关闭容器重启策略并停止容器进行排障

先保存需要的日志,并记录原来的重启策略。

对于直接由Docker管理、已经确认允许停机的目标容器,可以执行:

docker update --restart=no web
docker stop -t 30 web

第一条命令关闭该容器的自动重启策略,第二条命令停止容器。

30表示停止等待时间,单位为秒。超时后进程可能被强制终止,数据库等需要较长退出时间的服务,应按实际情况调整。

停止重启循环只是为了排查,不代表故障已经修复。

如果容器由面板或编排系统管理,应同时处理管理端的自动拉起规则,否则它仍可能重新启动或重建容器。

完成修复后,应恢复原来的策略。例如,原策略确实为unless-stopped时:

docker update --restart=unless-stopped web
docker start web

其他策略应按记录恢复,不要统一替换。Compose或面板管理的项目,也应保持其配置与预期一致。

8. 修改Compose配置后,如何正确生效?

如果问题来自Compose文件中的环境变量、启动命令或挂载设置,修改后先检查配置:

docker compose config -q

确认依赖服务已经正常运行,且允许目标服务短暂中断后,可以执行:

docker compose up -d --no-deps web

这里的web是Compose服务名称。--no-deps表示此次不启动依赖服务,因此不能用于跳过尚未解决的依赖故障。

仅执行docker compose restart不会应用Compose文件中修改后的环境变量等配置。 up会根据配置变化,在需要时重新创建服务容器。

重建前应确认业务数据已经正确挂载到数据卷或宿主机目录,并做好必要备份。只保存在容器可写层中的数据,不能依赖重建保留。

如果问题发生在镜像升级后,还应检查项目的升级说明和数据迁移要求。涉及数据库格式变化时,不要直接用旧版本程序连接已经升级的数据目录。

9. 常见问题与操作注意事项

显示unhealthy就一定会自动重启吗?

不会。普通Docker Engine的容器重启策略主要根据主进程退出处理,单纯健康检查失败不会自动触发重启。外部监控工具和编排系统可能另有处理规则。

为什么容器一直显示Up,网页仍然打不开?

Up只说明主进程存在。还需要检查服务监听地址、端口映射、反向代理、依赖服务和实际请求结果。

一直重启时无法执行docker exec怎么办?

先通过宿主机查看docker logs、docker inspect和挂载目录。容器尚未稳定运行时,不宜依赖反复尝试进入容器排查。

把重启策略改成always能修好吗?

不能。缺少配置、权限错误或内存不足没有解决时,持续重启通常只会重复同一个错误。

删除容器重新部署是不是最快?

应先保存日志、核对数据挂载并确认原因。不要把删除数据卷、执行docker compose down -v或清空Docker目录作为通用修复步骤。

10. 恢复后如何验证?

重新检查状态与重启次数:

docker ps -a --format 'table {{.Names}}\t{{.Status}}'
docker inspect --format '{{.RestartCount}}' web
docker logs --since 5m --tail 80 web

持续观察,确认:

  • 容器不再反复退出。

  • 重启次数没有继续增加。

  • 原来的启动错误不再重复。

  • 内存、磁盘等资源保持正常。

  • 网站、接口或数据库实际请求能够完成。

  • 重启策略已经恢复为预期配置。

Docker容器一直重启时,应先找到程序退出的原因,再处理自动恢复规则。通过状态、日志、退出码和资源记录交叉判断,通常能够更快定位问题。

如果需要联系莱卡云技术支持,建议提供故障时间及所在时区、容器名称、镜像版本、退出码、相关日志,以及近期配置或升级记录。提交资料前,请隐藏密码、访问令牌和数据库连接凭据。

按文档操作后还是不行,把机器编号、出问题的时间点和现象截图一起提工单,能少来回一轮。

提交工单