服务器没有上传新文件,磁盘使用率却一直增长;清理了一些镜像,过几天空间又不够了。遇到这种情况,可以检查 Docker 容器日志。
Docker 的 json-file 日志驱动会记录容器的标准输出和标准错误。如果没有配置轮转,日志文件默认不限制大小,应用持续输出错误信息或调试内容,就可能不断消耗磁盘空间。
本文适用于 Linux 上的 Docker Engine 和 Docker Compose V2,命令以 root 用户执行。处理顺序是:确认占用、定位容器、设置限额,再重建并验证。

1.先确认磁盘和 Docker 的占用情况
查看磁盘容量和 inode 使用情况:
df -h
df -i
df -h 用于检查磁盘空间;如果磁盘仍有容量,却无法创建文件,也要检查 df -i 是否显示 inode 已耗尽。
接着查看 Docker 的存储目录、默认日志驱动及资源占用:
docker info --format '存储目录:{{.DockerRootDir}} 默认日志驱动:{{.LoggingDriver}}'
docker system df
不要直接假定 Docker 数据都在 /var/lib/docker,部分服务器已经修改过存储位置。
另外,默认日志驱动和单个容器的实际配置可能不同,已有容器应单独检查。
2.找出日志体积较大的容器
下面的命令读取使用 json-file 驱动的容器日志文件大小,并按大小排序,列出前十项:
docker ps -aq | while IFS= read -r log_id; do
log_driver=$(docker inspect -f '{{.HostConfig.LogConfig.Type}}' "$log_id") || continue
[ "$log_driver" = "json-file" ] || continue
log_file=$(docker inspect -f '{{.LogPath}}' "$log_id") || continue
[ -f "$log_file" ] || continue
log_bytes=$(stat -c '%s' -- "$log_file") || continue
log_name=$(docker inspect -f '{{.Name}}' "$log_id") || continue
printf '%s\t%s\n' "$log_bytes" "${log_name#/}"
done | sort -nr | head -n 10
第一列是字节数,第二列是容器名称。该命令只读取文件大小,不修改日志;统计的是当前活动 JSON 日志,不包含已经轮转的历史文件,也不适用于 local、journald 等其他驱动。
Docker 官方提供的 .LogPath 字段可以用于定位容器日志路径。
找到目标容器后,将下面的 容器名 替换为实际名称,查看最近的日志:
docker logs --tail 200 --timestamps 容器名
重点关注是否反复出现数据库连接失败、权限错误、接口重试,或者大量调试信息。--tail 200 只读取末尾 200 行,方便快速检查。日志限额可以控制占用,但反复报错的原因仍需修复。
3.在 Compose 中设置日志轮转
进入原来的 Compose 项目目录,在需要限制日志的服务下面增加 logging 配置。
以下用 app 表示服务名,实际操作时保留该服务原有的镜像、端口、环境变量和数据挂载配置:
services:
app:
# 保留原有配置,在同一服务下新增 logging
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
这是一段配置示意,只把 logging 部分合并到原服务中,不要用它覆盖整个 Compose 文件。logging 与该服务的 image、ports、volumes 同级。
两个参数分别表示:
| 参数 | 作用 |
|---|---|
max-size: "10m" | 单个日志文件达到轮转阈值后切换文件 |
max-file: "3" | 最多保留三个日志文件,超出后淘汰最旧文件 |
按配置估算,每个容器的这类日志约保留 30MB。它是轮转策略,并非容器全部文件的磁盘配额;max-file 需要与 max-size 配合才有效。
4.确认数据持久化,再重建目标服务
修改日志配置后,单纯执行 docker restart 或 docker compose restart 不会让已有容器采用新的日志设置,需要重建容器。
重建前,先检查目标容器的数据挂载:
docker inspect --format '{{range .Mounts}}{{println .Type .Source "->" .Destination}}{{end}}' 容器名
对照应用实际的数据目录,确认数据库、上传文件等重要数据已经放在持久化卷或宿主机挂载目录中,并做好备份。
仅存在于容器可写层中的文件,会随着旧容器被移除而丢失;看到有挂载记录,也不代表所有重要目录都已经覆盖。
需要留存的旧容器日志也应提前导出。
在原 Compose 项目目录检查配置:
docker compose config -q
检查通过后,重建目标服务:
docker compose up -d --no-deps --force-recreate --no-build --pull never app
其中,app 是 Compose 文件中 services 下的服务名,需要替换为实际值。
该操作会短暂停止并重新创建目标服务,沿用现有本地镜像,不构建新镜像,也不启动依赖服务。应在能够接受短暂中断的时间执行。
5.验证日志配置和业务状态
检查目标服务的容器状态:
docker compose ps app
再读取实际生效的日志配置:
docker compose ps -aq app |
xargs -r docker inspect --format '{{.Name}} {{json .HostConfig.LogConfig}}'
正常应能看到类似内容:
{"Type":"json-file","Config":{"max-file":"3","max-size":"10m"}}
如果仍然没有限额,检查是否修改了正确的 Compose 文件、正确的服务,以及容器是否已经完成重建。
最后查看近期日志,并实际访问网站或应用:
docker compose logs --tail 50 app
旧容器移除后,其 Docker 日志会随之清理;再用 df -h 检查空间变化。如果空间仍然紧张,需要继续检查其他目录。
6.设置了日志限额,磁盘为什么还会增长?
这里需要区分两类日志:
| 日志类型 | 是否受上述配置控制 |
|---|---|
| 应用输出到标准输出、标准错误,由 Docker 收集的日志 | 是 |
应用自行写入 /app/logs 等目录的文件日志 | 否 |
如果应用把日志直接写入挂载目录,需要使用应用自带的保留策略,或为这些应用日志单独配置轮转。数据库文件、上传附件、备份和缓存,也不受 Docker 日志限额控制。
如果磁盘已经达到 100%,可以在接受业务中断的前提下,先停止持续写日志的服务:
docker compose stop app
随后通过扩容,或清理已经确认无用的普通文件恢复可用空间,再进行配置检查和重建。停止容器只能阻止它继续写入,不会自动释放已有日志。
不要直接删除 Docker 数据目录,也不要把手动删除、截断 Docker 管理的日志文件作为常规清理方式。官方文档提醒,这类外部操作可能干扰日志系统。
如果业务需要长期保留日志,应另外设置集中日志存储和保留周期。本地轮转会淘汰旧记录,无法同时承担完整的历史审计存储。






