Docker 容器启动失败,如何查看日志排查?
写在前面:为什么容器启动后查日志是第一件事
刚接触 Docker 的朋友,容器启动了又立刻退出、或者一直处于重启状态,第一反应往往是重新拉镜像或重建容器。
但真正高效的排查思路,是先查看日志——日志里通常直接告诉了你失败原因(端口被占用、配置文件错误、权限不足等)。
本文就围绕「Docker 容器启动失败,如何查看日志排查?
」这个场景,一步步教你用最常用的命令和技巧快速定位问题。
前置准备:确认环境并获取容器基础信息
开始排查前,先确认以下两点:
- Docker 已安装并运行:终端执行
docker version,能看到 Client 和 Server 版本信息即为正常。 - 容器已经启动过(哪怕失败了):如果容器还没创建,先执行
docker run或其他启动命令。
随后用 docker ps -a 列出所有容器(包括已停止的),记下目标容器的 NAME 或 CONTAINER ID。
例如输出中有个 CONTAINER ID 为 a1b2c3d4,Nginx 容器状态显示 Exited (1),这就是我们要查的对象。
分步操作:三个命令吃透容器日志
1. docker logs —— 查看运行期标准输出和标准错误
最直接的方法,语法非常简单:
docker logs <容器名或ID>
- 例如:
docker logs my-nginx或docker logs a1b2c3d4。 - 它会输出容器内进程打出的所有日志,包括启动时的错误信息。
- 如果日志太长,加
--tail 50只看最后 50 行:docker logs --tail 50 my-nginx。 - 想实时跟踪最新日志,加
-f:docker logs -f my-nginx(按Ctrl+C退出)。
典型情况:看到 Error: listen tcp :80: bind: address already in use 表示端口 80 已被占用;
看到 exec: "nginx": executable file not found in $PATH 说明启动命令写错了。
2. docker inspect —— 查看容器详细配置和退出码
有时候 docker logs 没输出(因为进程根本没启动),可以用 docker inspect 看看容器的元数据:
docker inspect <容器名或ID>
这会输出大量 JSON 格式信息,我们重点关注几个字段:
State.Status:当前状态(exited、running 等)State.ExitCode:退出码,非 0 表示异常退出。常见退出码:1 表示一般错误;137 表示被 SIGKILL 杀死(比如 OOM);139 表示段错误。State.Error:如果启动过程中有底层错误,这里会直接写明。Config.Cmd:容器启动时执行的命令,检查是否写对了。HostConfig.Binds/Mounts:挂载的卷,看路径是否存在、权限是否正确。
如果只看退出码和错误信息,可以加格式过滤:
docker inspect --format='{{.State.ExitCode}} {{.State.Error}}' my-nginx
3. docker logs + docker events —— 跟踪启动瞬间的日志
如果容器不断重启(状态为 Restarting),日志可能被滚动覆盖。
此时可以用 docker events --filter 监听容器启动事件,再结合 docker logs 看容器被杀死前的输出:
# 新开一个终端,先监听事件
docker events --filter 'container=my-nginx' --format '{{json .}}'
# 在另一个终端启动或重启容器
docker restart my-nginx
观察事件输出中的错误信息,或者直接查看容器在被杀死前最后几秒的日志:
docker logs --tail 20 my-nginx
避坑指南:新手最容易忽略的细节
- 日志为空不代表没错误:如果容器进程直接崩溃,标准输出可能没来得及写。此时用
docker inspect看 ExitCode 和 Error 更靠谱。 - 不要只用
docker logs看一次就放弃:有些错误只出现在启动瞬间,加--follow或--since 5m看过去几分钟的日志。 - 挂载目录权限问题:如果容器内进程以非 root 用户运行,而宿主机挂载的目录权限为 755 且属主为 root,容器内可能无法写入。检查
docker inspect中的Mounts和宿主机的目录权限。 - 镜像启动命令错误:使用
docker run --entrypoint sh <镜像名>进入容器内部手动调试,比反复看日志更高效。 - 网络端口冲突:
docker: Error response from daemon: driver failed programming external connectivity说明宿主机端口已被占用,可以用ss -tlnp | grep <端口>查谁占用了。
效果验证:确认问题已修复并恢复正常
假设你根据日志找到了原因(比如端口冲突),修复后(如换一个映射端口),执行:
# 删除失败的旧容器
docker rm my-nginx
# 重新启动(注意修改端口)
docker run -d -p 8080:80 --name my-nginx nginx
然后验证:
docker ps查看容器状态是否为Up状态。docker logs --tail 10 my-nginx确认没有新的错误日志。- 用浏览器或
curl http://localhost:8080测试服务是否正常响应。 - 如果容器依然异常,重复上述步骤再次查看日志,直到问题解决。
总结:遇到 Docker 容器启动失败,别急着重建容器,先按本文步骤查看日志和容器详情,80% 的问题都能在几分钟内定位。
日志就是你最好的排错向导,用好 docker logs、docker inspect 和 docker events,再配合避坑要点,新手也能快速排查。