家用住宅主机Linux容器日志自动清理磁盘
家用Linux主机容器日志自动清理磁盘,三步释放空间
家里的小主机或NAS上跑着Docker容器,时间一长就会发现磁盘空间越来越少,检查后往往发现是容器日志在悄悄膨胀。
如果不做处理,一次日志累积就能吃掉几十GB。
本文针对 家用住宅主机Linux容器日志自动清理磁盘 这个真实场景,提供一套不用每天盯着、自动执行的方案,让新手也能一次配置长期省心。
为什么容器日志会占满磁盘
Docker默认把每个容器的标准输出(stdout/stderr)写入宿主机的JSON日志文件。
默认情况下,Docker不会限制日志文件大小或数量,日志文件越长越大,直到磁盘报警。
典型症状是df -h发现根分区空间骤降,通过du -sh /var/lib/docker/containers/*/logs/可以看到个别日志可能已经大到几GB。
动手前需要确认的准备工作
- 你有一台运行Linux的家用主机(Ubuntu/Debian/CentOS等),已经安装Docker。
- 有sudo权限或root权限。
- 确认当前Docker日志存储路径:默认是
/var/lib/docker/containers/。如果改过路径,后续配置中对应调整即可。 - 建议先通过
docker info | grep -i logging查看当前日志驱动,默认通常是json-file。
核心步骤:从源头限制+定时清理双管齐下
1. 全局限制:修改Docker守护进程配置
这是最推荐的做法——在Docker启动时就给每个容器设定日志上限。
编辑或创建/etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
说明:max-size表示单个日志文件最大10MB,max-file表示保留最近3个文件。这样每个容器日志最多占用30MB。
保存后重启Docker:sudo systemctl restart docker。注意:重启会短暂中断运行中的容器,建议先排好维护时间。
2. 定向清理:用logrotate对付已膨胀的日志
如果你不想重启Docker,或者想清理已经存在的超大日志,可以借助Linux自带的logrotate。
创建一个配置文件/etc/logrotate.d/docker-containers:
/var/lib/docker/containers/*/*.log {
rotate 7
daily
compress
missingok
delaycompress
copytruncate
size 10M
}
rotate 7:保留最近7份轮转后的日志。daily:每天执行一次。copytruncate:在不中断容器写入的前提下复制并截断原日志文件,这是重点。
配置好后可以用sudo logrotate -d /etc/logrotate.d/docker-containers测试(-d是调试模式)。
3. 定时执行:用crontab让清理自动化
logrotate默认每天由系统cron触发一次。
如果你想让清理更频繁(比如每小时),可以添加自定义cron任务。
执行crontab -e,添加一行:
0 * * * * /usr/sbin/logrotate -f /etc/logrotate.d/docker-containers >/dev/null 2>&1
这条命令表示每小时的第0分钟强制执行一次logrotate。-f参数强制轮转,即使日志大小未达到条件也会触发。
避坑指南:新手最容易翻车的几个点
- 不要直接删日志文件:很多人图快直接用
rm删除/var/lib/docker/containers/*/*.log,但Docker进程仍然持有文件句柄,磁盘空间不会立即释放,直到容器重启。正确做法是truncate -s 0清空文件内容,或者用上面介绍的copytruncate方式。 - daemon.json语法错误:编写时务必注意JSON格式,末尾不要有多余逗号。改好后先运行
dockerd --validate检查配置(如果Docker版本支持)。 - 容器日志依然暴涨:如果某些容器(比如数据库、代理)写入极快,建议单独为它们设置更严格的限制,可以在
docker run时加--log-opt max-size=5m --log-opt max-file=2。 - logrotate不生效:检查logrotate的版本是否支持
copytruncate(RHEL5及以下可能不支持)。另外确保logrotate服务已启用:sudo systemctl enable logrotate.timer。
验证清理是否生效的简单方法
- 执行
sudo du -sh /var/lib/docker/containers/*/logs/查看日志总量。 - 等一两天后再运行同样的命令,看总量是否趋于稳定在设定阈值附近。
- 观察
docker logs --tail 5 容器名是否能正常输出最新日志,说明轮转没有影响容器运行。 - 用
dmesg或journalctl -u docker检查是否有日志相关报错。
常见问题(FAQ)
Q:我改完daemon.json后需要重启所有容器吗?
A:不需要重启容器,但需要重启Docker守护进程。已经运行中的容器会继续使用之前的日志驱动和选项,新启动的容器才应用新配置。你可以通过docker inspect 容器名 | grep LogConfig查看当前正在使用的日志配置。
Q:logrotate中的copytruncate会丢失最新几秒的日志吗?
A:理论上在拷贝和截断之间会有一个极短的时间窗口,但绝大多数场景下影响可忽略。如果对日志完整性要求极高,可以考虑Docker的fluentd或syslog驱动。
Q:我不想每小时执行,用默认的logrotate每天一次够吗?
A:主要看你的日志写入量。如果单个容器每天产生超过10MB日志,建议缩短周期。在家用场景下,默认daily加上size 10M通常够用。
Q:除了日志,还有哪些地方容易占磁盘?
A:Docker的镜像层、停止容器未清理的卷(volume)也会占空间。定期用docker system prune清理无用资源也是好习惯。
最后
通过“全局限制+定期轮转+定时触发”这三步,你基本可以实现家用住宅主机上Linux容器日志的自动清理,彻底告别磁盘被日志填满的烦恼。
配置完成后先观察一周,再根据实际日志量微调参数。
如果你在操作中遇到任何异常,优先回看本文的避坑部分,或检查logrotate的调试输出定位问题。