Docker 日志查看与调试技巧(排查问题必备)
容器起来了,服务却访问不到。没有报错,没有提示,只有一个沉默的进程悄悄退出。
这种情况是 Docker 使用中最让人抓狂的场景之一——不是挂了,是"失踪"了。而解决这类问题,99% 的突破口都藏在日志里。遗憾的是,很多开发者只会反复 docker ps,却从没认真看过日志。
这篇文章完整梳理 Docker 日志的查看方式、驱动配置、多容器聚合,以及调试容器的实用手段——从"看不到日志"到"定位问题根源",走一遍完整流程。
Docker 日志的工作原理
在具体命令之前,先搞清楚日志是怎么来的。
容器里的进程把内容写到 stdout 和 stderr,Docker 的日志驱动捕获这两个流,决定把日志存到哪、怎么存。
这个流程决定了一件事:如果程序把日志写到文件而不是 stdout,docker logs 就看不到任何内容。这是初学者最常踩的坑之一。
基础命令:docker logs
docker logs my-container
这个命令输出容器启动以来的所有日志。容器跑久了日志会很多,通常需要配合参数:
# 只看最后 100 行
docker logs --tail 100 my-container
# 实时跟踪日志输出
docker logs -f my-container
# 显示时间戳
docker logs -t my-container
# 组合使用:带时间戳实时跟踪
docker logs -f -t my-container
# 查看某个时间点之后的日志
docker logs --since 2026-05-10T10:00:00 my-container
# 查看最近 5 分钟的日志
docker logs --since 5m my-container
--since 参数在排查"刚才出了什么问题"时非常有用,比从几千行日志里翻找要快得多。
日志驱动:日志存在哪
Docker 默认使用 json-file 驱动,日志文件存放在:
/var/lib/docker/containers/<container-id>/<container-id>-json.log
查看当前 Docker 默认日志驱动:
docker info | grep "Logging Driver"
查看某个容器使用的日志驱动:
docker inspect my-container | grep -A 5 '"LogConfig"'
各日志驱动的特点如下:
配置日志轮转
json-file 驱动默认没有轮转限制,单个日志文件可以无限增长,时间久了会把磁盘撑爆。正确做法是在启动时配置限制:
# 启动时指定日志驱动和选项
docker run \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
my-image
或者在 docker-compose.yml 中统一配置:
services:
app:
image: my-image
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
max-size=10m 表示单个日志文件最大 10MB,max-file=3 表示最多保留 3 个轮转文件,超出后自动删除最旧的。
也可以修改 Docker 全局默认配置,对所有容器生效,编辑 /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
修改后重启 Docker:sudo systemctl restart docker。
多容器日志聚合查看
实际项目往往由多个容器构成,逐个查看效率很低。
方式一:Docker Compose
# 查看所有服务的日志
docker-compose logs -f
# 只查看某个服务
docker-compose logs -f app
# 只看最后 50 行
docker-compose logs --tail 50
方式二:dozzle(推荐用于本地开发)
dozzle 是一个轻量级的 Web 日志查看工具,一条命令启动:
docker run --name dozzle -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 8080:8080 \
amir20/dozzle
浏览器访问 http://localhost:8080,可以看到所有容器的实时日志,支持关键词搜索、颜色高亮、正则过滤,比命令行直观很多。
注意:dozzle 挂载了 Docker socket,具备读取所有容器信息的权限,生产环境使用需评估安全风险,建议只在开发环境部署。
调试容器的实用手段
日志只是起点,很多问题还需要深入容器内部排查。
查看容器详细配置
docker inspect my-container
输出内容包括环境变量、挂载点、网络配置、端口映射、重启策略等完整信息,适合检查"配置有没有传对"。
筛选特定字段:
# 只查看环境变量
docker inspect my-container --format '{{.Config.Env}}'
# 只查看挂载点
docker inspect my-container --format '{{json .Mounts}}' | python3 -m json.tool
# 查看容器 IP
docker inspect my-container --format '{{.NetworkSettings.IPAddress}}'
进入容器排查
# 进入容器(优先用 bash)
docker exec -it my-container /bin/bash
# 没有 bash 时用 sh
docker exec -it my-container /bin/sh
进入后常用的排查命令:
# 查看进程
ps aux
# 查看端口监听
netstat -tlnp
# 或
ss -tlnp
# 测试服务连通性
curl -v http://localhost:8080
# 查看 DNS 解析
cat /etc/resolv.conf
cat /etc/hosts
# 查看磁盘空间
df -h
实时监控资源使用
# 监控所有容器
docker stats
# 只看指定容器
docker stats my-container
输出包括 CPU 使用率、内存占用和限制、网络 IO、磁盘 IO,适合排查"服务变慢"或"内存泄漏"类问题。
查看容器内进程
docker top my-container
显示容器内所有进程的 PID、所属用户和 CPU/内存占用,无需进入容器。
常见问题排查
容器启动后立即退出
# 查看退出原因
docker logs my-container
# 查看退出码
docker inspect my-container --format '{{.State.ExitCode}}'
退出码含义:0 正常退出,1 程序错误,137 OOM 或被强杀,143 收到 SIGTERM 信号。
常见原因:Dockerfile CMD 写的是一次性脚本,执行完就退出了,需要改成持续运行的前台进程。
服务启动了但访问不到
按顺序排查:
# 1. 确认端口映射
docker ps --format "table {{.Names}}\t{{.Ports}}"
# 2. 进入容器确认服务在监听
docker exec -it my-container netstat -tlnp
# 3. 确认服务没有只绑定 127.0.0.1
# 如果绑定的是 127.0.0.1:8080,外部是访问不到的,需要改成 0.0.0.0:8080
磁盘报 “No space left on device”
# 查看 Docker 各类资源占用
docker system df
# 清理已停止容器、无用镜像、网络
docker system prune -a
# 只清理悬空镜像
docker image prune
日志输出有延迟
很多编程语言的 stdout 默认有缓冲,写了内容不会立刻输出。常见解决方式:
# Python:禁用缓冲
python -u app.py
# 或设置环境变量
ENV PYTHONUNBUFFERED=1
# Node.js:默认无缓冲,通常不需要处理
日志管理几条原则
- 生产环境关掉 DEBUG 级别:DEBUG 日志量通常是 INFO 的数倍,既浪费存储又增加查找噪音
- 敏感信息不入日志:密码、token、手机号做脱敏处理,
****替换,而不是直接打印 - 配置日志轮转:不管是
max-size还是 logrotate,选一种,生产环境必须有 - 重要系统接外部日志平台:ELK(Elasticsearch + Logstash + Kibana)或 Grafana Loki,方便跨容器检索和告警
小结
Docker 日志排查的核心路径很清晰:
大多数容器问题,按这条路走下来都能找到答案。与其凭感觉重启容器,不如先把日志看完。
更多推荐

所有评论(0)