Restarting (1) 表示容器主进程启动后立即退出,退出码为1,非重启次数;应先禁用重启策略使状态固化为Exited,再通过docker inspect查ExitCode、OOMKilled及docker logs --previous捕获启动日志定位根因。

容器在 Docker Desktop 上反复显示 Restarting,不是镜像坏了,也不是 Mac 或 Windows 本身有问题,而是它卡在了“启动即退出→被重启策略拉起→再退出”的死循环里。关键不是让它快点起来,是先让它停住、说出错在哪。
用 docker inspect 看清退出码和真实状态
别只盯着 docker ps 里那行 Restarting (1) ——括号里的 1 是上一次进程退出时返回的 exit code,不是重启次数。它说明主进程主动报错了,但没告诉你错哪。
- 先停掉自动重启:运行
docker update --restart=no(必须是 stopped 状态,可先docker stop) - 再查状态:
docker inspect--format='{{.State.Status}} {{.State.ExitCode}} {{.State.OOMKilled}}' - 重点关注三个字段:
-
.State.Status:应为exited,不是running或restarting -
.State.ExitCode:常见值有1(应用逻辑错误)、137(被 OOMKilled)、143(收到 SIGTERM 后未退出) -
.State.OOMKilled:若为true,哪怕ExitCode是137,也得去查内存限制和宿主机资源
-
用 docker logs 抓住“来不及刷出”的启动日志
Docker Desktop 的容器常因启动太快崩溃,导致 docker logs 返回空或只有几行。这不是没日志,是日志根本没来得及 flush 到磁盘就被杀掉了。
- 强制获取最近一次退出前的日志:
docker logs --tail 200 --timestamps - 如果为空,加
--previous(仅限已重启过一次的容器):docker logs --previous --tail 100 - 更稳妥的做法:临时改 CMD,把启动命令包一层
sh -c 'your-command 2>&1 | tee /tmp/start.log; tail -n 20 /tmp/start.log',确保 stderr 强制落地 - 注意:Docker Desktop for Mac/Windows 默认日志驱动是
json-file,但底层 VM(hyperkit / WSL2)可能丢日志;如持续为空,优先怀疑进程生命周期
检查 Docker Desktop 资源分配与 WSL2/hyperkit 限制
Docker Desktop 不是“本地 Docker”,它跑在轻量虚拟机里。Mac 上是 hyperkit,Windows 上是 WSL2 —— 容器崩溃常源于这个中间层资源不足,而非容器配置本身。
- Mac 用户:打开 Docker Desktop → ⚙️ Settings → Resources → Memory,确认没锁死在 2GB;建议调到 4–6 GB(尤其跑 Java/Node.js)
- Windows 用户:检查 WSL2 分配,运行
wsl -l -v,再对 docker-desktop-data 执行:wsl --shutdown && wsl --unregister docker-desktop-data(⚠️会清空所有镜像和容器,慎用) - 通用验证法:运行一个“压力测试容器”:
docker run --rm -m 3g alpine:latest sh -c 'dd if=/dev/zero of=/tmp/big bs=1M count=2500 && sync',看是否直接报ExitCode 137 - 别忽略 DNS:Docker Desktop 默认用 host 的 DNS,但某些企业网络会拦截
8.8.8.8;可在 Settings → Docker Engine 中加"dns": ["1.1.1.1"]
绕过重启策略,手动执行 CMD 验证启动逻辑
当 ExitCode 1 频发且日志无有效线索,大概率是 ENTRYPOINT/CMD 在容器内根本跑不起来——比如路径错、权限错、动态库缺失、或依赖服务(如 Redis、PostgreSQL)还没就绪就急着连。
- 进容器 shell(即使它秒退):
docker run -it --rm --entrypoint /bin/sh,然后手动敲一遍 CMD 里的命令 - 检查文件是否存在:
ls -l /app/start.sh,注意 Windows 换行符(CRLF)会导致/bin/sh^M: bad interpreter - 检查权限:
stat -c "%a %U:%G %n" /app/start.sh,非 root 容器里脚本必须有 +x,且不能依赖 root 才有的 capability - 模拟最小依赖环境:删掉所有
depends_on、healthcheck、restart,只保留image和command,看能否稳定输出一行 “OK”
最常被跳过的一步:Docker Desktop 的 Restarting 循环,往往不是应用代码的问题,而是你没意识到它正运行在一个资源受限、DNS 可能被劫持、且日志管道极不稳定的虚拟化中间层里。停掉重启策略、拿到真实退出码、验证宿主机资源配额——这三步做完,80% 的“神秘重启”就自然浮出水面了。











