容器启动失败关键在退出码与日志:先执行docker logs <container_id>查报错,再用docker inspect <container_id> | grep -A 5 "State"确认ExitCode和FinishedAt,排除正常终止;若日志为空则交互式运行定位根本原因。
容器启动失败,关键在看退出码(exitcode)和对应日志。docker 容器一启动就变成 exited (x),说明 pid 1 进程已终止,x 就是它的退出状态码——它不是随机数字,而是定位问题的直接线索。
立即查 ExitCode 和日志
别只扫一眼 docker ps -a,必须马上执行两步:
-
看日志:运行
docker logs <container_id>,绝大多数错误(配置错、连不上数据库、脚本报错)都会输出在这里; -
看退出详情:运行
docker inspect <container_id> | grep -A 5 "State",确认ExitCode值和FinishedAt时间,排除被docker stop正常终止的情况(ExitCode 0 或 143); - 如果日志为空且秒退,说明进程根本没来得及打印——这时用
docker run -it <image> <command>交互式运行,实时观察报错。
按 ExitCode 快速对症
常见非零退出码含义明确,可直接缩小排查范围:
-
ExitCode 1:通用错误。常见于 Shell 脚本语法错、Python/Node.js 程序抛未捕获异常、或命令本身执行失败(如
curl请求超时未处理); -
ExitCode 2:多因启动命令写错。例如
docker run nginx echo hello,容器执行完echo就退出,Nginx 根本没启动; -
ExitCode 127:命令找不到。典型如
CMD ["/app/start.sh"],但镜像里压根没这个文件,或路径拼写错误; -
ExitCode 137:内存被杀。容器实际内存超限,Linux OOM Killer 强制终止 PID 1。可用
docker stats查历史内存峰值,或dmesg | grep -i "killed process"确认; - ExitCode 139:段错误。常见于 C/C++ 程序访问非法内存、动态库版本不匹配,或用了宿主机不支持的 CPU 指令集(如 AVX);
检查 CMD/ENTRYPOINT 是否合理
很多“秒退”本质是主进程设计不当:
- 确保 CMD 或 ENTRYPOINT 启动的是**前台长期运行的进程**,不是一次性命令(比如
ls、echo、sh -c "xxx &"); - 若用 Shell 形式(如
CMD echo hello),Docker 会调用/bin/sh -c,子进程退出后容器即停;改用 Exec 形式(CMD ["echo", "hello"])更可控,但注意它不会触发 Shell 功能(如变量展开、管道); - Web 服务类镜像(如 Nginx、Python Flask)需确认是否监听
0.0.0.0而非127.0.0.1,否则外部无法访问,健康检查失败也可能间接导致重启策略触发退出。
验证镜像与运行环境一致性
有些退出码背后是底层环境不匹配:
-
权限问题(ExitCode 126):脚本缺少
+x权限,或二进制程序架构不兼容(如 x86_64 镜像跑在 ARM 主机上); -
内核/模块缺失:某些镜像依赖特定内核功能(如 overlay2 存储驱动),宿主机内核版本过低或未加载对应模块会导致
dockerd启动失败(表现为systemctl start docker报status=1/FAILURE); -
磁盘只读:系统异常重启可能导致根分区挂载为
ro,此时dockerd无法写入/var/lib/docker,直接退出。用mount | grep " / "检查,必要时重启修复。


















