Docker 服务运行一段时间后,服务器可能突然出现磁盘空间不足、应用无法写入文件或数据库报错等问题。如果容器持续输出大量日志,又没有配置日志轮转,日志文件就可能不断增长。
Docker 默认的 json-file 日志驱动没有开启大小限制。对于频繁输出访问日志、调试信息或重复错误的应用,日志占用可能逐渐超过业务数据本身。
处理这类问题,可以按照“确认磁盘占用、定位日志来源、配置轮转、重建目标容器、验证结果”的顺序操作。
本文适用于普通 Linux 服务器上的 Docker Engine 和 Docker Compose V2,主要处理 json-file 驱动收集的容器标准输出和标准错误日志。

一、确认 Docker 数据所在磁盘是否已满
先查询 Docker 的数据目录:
docker_data_dir=$(sudo docker info --format '{{.DockerRootDir}}')
printf '%s\n' "$docker_data_dir"
确认正常返回目录后,检查该目录所在文件系统的容量和 inode:
sudo df -h "$docker_data_dir"
sudo df -i "$docker_data_dir"
重点查看两个指标:
| 指标 | 含义 | 常见情况 |
|---|---|---|
Use% | 磁盘容量使用率 | 大日志、大文件或业务数据占满空间 |
IUse% | inode 使用率 | 大量小文件耗尽可用 inode |
Docker 的数据目录可能经过调整,因此应根据实际查询结果检查,不能只盯着系统盘或固定的 /var/lib/docker 路径。
二、定位体积较大的容器日志
先查看各容器的名称、日志驱动和日志路径:
sudo docker ps -aq |
xargs -r sudo docker inspect --format \
'{{.Name}} | {{.HostConfig.LogConfig.Type}} | {{.LogPath}}'
重点关注日志驱动为 json-file 的容器。
在普通 Docker Engine 环境中,可以通过文件元数据列出当前体积最大的 JSON 日志文件:
sudo find "$docker_data_dir/containers" \
-maxdepth 2 \
-type f \
-name '*-json.log' \
-printf '%s\t%p\n' |
sort -nr |
head -n 10
第一列为文件大小,单位是字节;第二列为文件路径。结合前一条命令,就能找到对应容器。
这个列表只包含当前的 *-json.log 文件,没有统计已轮转的历史日志。如果找不到明显的大日志,应继续检查数据卷、镜像和应用自行写入的文件。
如果容器使用的是 local、journald 或其他日志驱动,应按对应驱动排查。
三、检查容器为什么持续输出日志
以下以容器名 myapp-app-1 为例,请替换成实际名称:
container_name='myapp-app-1'
查看该容器的日志配置:
sudo docker inspect --format \
'{{json .HostConfig.LogConfig}}' \
"$container_name"
如果驱动为 json-file,但配置中没有 max-size,通常意味着没有设置单个日志文件的大小限制。
接着查看最近的日志:
sudo docker logs \
--since 30m \
--tail 200 \
--timestamps \
"$container_name"
优先检查是否存在以下情况:
- 数据库连接失败后不断重试。
- 外部接口请求失败并持续打印错误。
- 生产环境开启了大量调试输出。
- 程序进入异常循环。
- 每次健康检查都输出较长内容。
日志轮转可以控制保留量,但持续报错仍需要修复。否则,即使磁盘占用得到控制,应用仍可能不断消耗 CPU、网络或磁盘写入资源。
四、在 Docker Compose 中配置日志轮转
进入原来的 Compose 项目目录,编辑实际使用的 compose.yaml 或 docker-compose.yml。
如果原部署使用了 -f、-p 或 --env-file 参数,后续 Compose 命令也应保持相同参数,确保操作的是原项目。
在需要限制日志的服务下增加 logging 配置。下面仅展示配置位置,原有的镜像、端口、环境变量和数据挂载等字段应继续保留:
services:
app:
# 保留此服务原有的其他配置
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
其中,app 是 Compose 文件中的服务名,需要替换成实际服务名。
| 参数 | 作用 |
|---|---|
driver: json-file | 使用 JSON 文件日志驱动 |
max-size: "10m" | 日志文件达到指定大小后触发轮转 |
max-file: "3" | 最多保留 3 个日志文件,包含当前文件 |
max-file 需要与 max-size 配合使用。轮转过程中,超过保留数量的旧日志会被删除,有长期留存需求时应另行采集日志。
这些限制按容器分别计算。多个容器的日志总占用会累加,应用自行写入数据卷的日志也不包含在这个限制内。
修改完成后,检查 Compose 配置:
sudo docker compose config -q
没有错误输出且命令成功结束,再继续下一步。如果出现缩进、字段或变量错误,应先修正配置。
五、确认数据持久化,再重建目标容器
日志配置属于容器创建时的配置。修改 Compose 文件后,需要重建对应容器才能应用。
重建会丢弃旧容器的可写层及其本地日志。操作前应确认数据库、上传文件、配置文件等重要数据已经持久化,并完成必要备份。
查看当前容器的数据挂载:
sudo docker inspect --format \
'{{range .Mounts}}{{println .Type .Source "->" .Destination}}{{end}}' \
"$container_name"
检查业务数据目录是否对应命名卷或宿主机挂载目录。如果重要数据只保存在容器内部,应先迁出或备份。
确认原有挂载配置保持正确,并且能够接受目标服务短暂中断后,在原 Compose 项目目录执行:
sudo docker compose up -d \
--no-deps \
--force-recreate \
--pull never \
--no-build \
app
这里的 app 是 Compose 服务名,不一定与容器名相同。
这条命令会重建指定服务,不主动启动依赖服务,也不拉取镜像或构建镜像。如果本地缺少所需镜像,需要先解决镜像问题。
旧容器由 Docker 正常移除后,其关联的本地日志也会被回收。原有业务数据能否保留,取决于数据持久化和挂载配置是否正确。
六、验证日志限制是否真正生效
先查看服务状态:
sudo docker compose ps -a app
再检查新容器的实际日志配置:
sudo docker compose ps -aq app |
xargs -r sudo docker inspect --format \
'{{.Name}} {{json .HostConfig.LogConfig}}'
确认输出中包含:
{
"Type": "json-file",
"Config": {
"max-file": "3",
"max-size": "10m"
}
}
接着检查服务日志:
sudo docker compose logs \
--since 5m \
--tail 100 \
app
最后重新查看磁盘空间:
sudo df -h "$docker_data_dir"
除了容器状态,还应实际访问网站、接口或应用,确认业务正常。如果旧日志已经回收,但磁盘占用仍然较高,就需要继续检查其他容器和业务数据目录。
七、几种容易遇到的情况
磁盘已经 100%,无法重建容器怎么办?
如果应用仍在大量输出日志,可以先在原项目目录停止对应服务:
sudo docker compose stop app
停止服务会造成业务中断,也不会自动释放已有日志空间。随后需要扩容对应文件系统,或清理已经确认可以删除的临时文件,为 Docker 恢复操作留出空间,再执行重建。
能直接删除或清空 Docker 的 JSON 日志文件吗?
Docker 官方说明,这些文件应由 Docker 守护进程管理,外部工具直接修改可能干扰日志系统。因此,日常处理应通过配置轮转和正常管理容器完成,避免直接删除、截断 Docker 管理的日志文件。
执行 docker compose restart 能应用新配置吗?
不能。restart 只重启现有容器,不会按修改后的 Compose 配置重新创建容器,因此不能用它替代重建步骤。
修改 daemon.json 后,老容器会自动获得日志限制吗?
不会。全局日志默认配置主要影响之后创建的容器,现有容器仍保留创建时的日志设置。需要更新现有容器时,仍应按原部署方式重建。
应用写入 /app/logs 的文件也会自动轮转吗?
不一定。本文配置控制的是 Docker 收集的标准输出和标准错误。应用直接写入文件的日志,应通过应用自身的日志设置或对应的文件轮转方案管理。
完成配置后,Docker 可以按设定的大小和数量保留容器日志。后续仍应观察磁盘增长趋势,并修复重复报错,让日志既能用于排查问题,也不会持续挤占业务空间。






