容器起不来的排查路径
容器启动失败的原因通常落在四层:启动命令与环境变量(配置层)、文件与目录权限(挂载层)、网络与端口(连接层)、镜像本身(内容层)。有效的排查是有序收敛:先拿状态与退出码确定失败层级,再看日志与引擎记录缩小范围,最后用同一镜像开交互容器手工复现,把问题定位到具体一行配置。
基本信息
| 第一步 | docker ps -a 看状态、退出码与重启次数 |
|---|---|
| 第二步 | docker logs --tail 200 看应用输出 |
| 第三步 | docker inspect 看 State.Error、Health 与配置项 |
| 第四步 | 同镜像开交互容器手工复现启动命令 |
| 辅助命令 | docker events 看生命周期事件、docker stats 看资源 |
| 常见诱因 | 命令不存在、权限不足、端口冲突、依赖未就绪、环境变量缺失 |
典型使用场景
- 发布后容器反复重启,需要快速定位是配置还是依赖问题
- 容器启动即退出,日志几乎没有输出
- 健康检查一直失败,容器被编排平台反复重建
- 挂载目录权限变化导致启动失败
- 端口被占用,容器无法绑定监听地址
五步排查
五步排查
# 一、状态与退出码:先确定失败层级
docker ps -a --filter name=web
docker inspect -f 'status={{.State.Status}} exit={{.State.ExitCode}} err={{.State.Error}} restarts={{.RestartCount}}' web
# 二、应用输出(失败往往在最后几行)
docker logs --tail 200 web
# 三、引擎侧事件与健康检查
docker events --filter container=web --since 30m | tail -20
docker inspect -f '{{json .State.Health}}' web
# 四、清除入口,用同镜像手工复现启动命令
docker run --rm -it --entrypoint sh app/web:1.0
docker run --rm -it --entrypoint sh app/web:1.0 -c 'node server.js'
# 五、核对运行时配置:挂载、环境变量、命令
docker inspect -f '{{json .Mounts}}' web
docker inspect -f '{{json .Config.Env}}' web
docker inspect -f '{{json .Config.Cmd}} {{json .Config.Entrypoint}}' web现象与诱因对照
| 现象 | 常见诱因 | 处理方向 |
|---|---|---|
| 启动即退出,日志为空 | 命令不存在或入口写错 | 核对镜像内命令与入口配置 |
| 报权限拒绝 | 挂载目录或文件属主不匹配 | 调整属主或运行用户 |
| 报端口被占用 | 宿主端口已被其他进程或容器使用 | 换端口或停掉占用方 |
| 连不上依赖服务 | 网络归属不对或依赖未就绪 | 核对网络与启动顺序 |
| 健康检查失败 | 探针命令不存在或路径不对 | 修正探针或镜像内容 |
| 重启次数不断增长 | 进程无法稳定运行 | 先停重启策略再排查 |
日志为空不等于没有问题:进程可能在打印任何内容之前就退出,这时退出码与引擎错误字段是唯一线索。
改动参数或镜像后要重建容器:只 restart 仍会使用旧配置,容易得出「改了没用」的错误结论。