40G 系统盘的尴尬
阿里云 ECS 新用户最常用的配置是 20-40G 系统盘。刚装好系统那会觉得够用,跑几个服务就开始报警。前段时间我的 40G 系统盘就触到了 92% 的线,只剩 3.2G 可用——这个数字看起来还有空间,实际上 Docker 拉个大镜像就能炸。
这台服务器运行的是 9Router AI 网关、Hermes Agent 和一些 Docker 容器。不是日志写满了,是开发工具链(pip/npm 缓存)、AI 服务数据、Docker 镜像这些东西慢慢堆起来的。市面上大多数磁盘清理教程只讲删日志和清 /tmp,但实际吃空间的大头根本不是这些。
逐层 du 排查法
不靠猜,直接看数据。从根目录开始层层深入。

第一步,定位哪些目录最大:
du -h --max-depth=1 / 2>/dev/null | sort -rh | head -10
结果很清晰:/root(~15G)和 /var(~7.5G)占了大多数。
第二步,深入每个大目录:
# /root 的分析
du -h --max-depth=1 /root 2>/dev/null | sort -rh | head -10
# /var 的分析
du -h --max-depth=1 /var 2>/dev/null | sort -rh | head -10
几个关键发现:
/root/.hermes→ 5.1G(Agent 运行环境)/root/.9router→ 4.5G(网关数据库和备份)/var/lib/containerd→ 4.6G(Docker 镜像)/root/.cache→ 1.4G(工具链缓存)/root/backup→ ~1G(系统备份)
这里有个让我意外的点:日志完全不是问题。/var/log 只有 173M。真正的大头是 AI 服务的运行数据和开发工具链的缓存。
分级清理方案
把找到的大文件按风险分成三个等级,从零风险到中风险,每个等级独立执行。

Tier 1:零风险,说清就清
这些操作不影响任何正在运行的服务:
# Python 缓存
uv cache clean # ~139M
pip cache purge # ~324M
# Node 缓存
npm cache clean --force # ~356M
# 系统日志(限制 journal 大小)
journalctl --vacuum-size=100M # 释放约 50M+
小计释放:约 870M。这些缓存本质上是加速用的,删了只是下次安装包时慢一点,不影响运行。
Tier 2:低风险,确认后执行
这些项目当前不用,但未来可能需要:
| 项目 | 释放空间 | 说明 |
|---|---|---|
| Playwright 浏览器缓存 | 622M | 删除后如要跑脚本需 playwright install |
| 旧 Hermes state-snapshots | 398M | 保留最近一份即可 |
| Docker 构建缓存 | 254M | docker builder prune -f |
Playwright 的 Chromium 浏览器缓存有 622M——如果在服务器上不跑浏览器自动化,这部分完全是闲置的。
Tier 3:中风险,确认服务状态后再操作
这些涉及生产服务的数据,操作前要确认影响:
-
9Router 数据库备份(3.3G):
/root/.9router/db/backups/下积累的历史备份。9Router 是 AI 网关核心服务,如果 DB 有异地备份或实时数据正常,这些历史备份可以删。但这是最后的防线,删之前确定其他备份方案正常。 -
Docker 镜像(~2.2G):
opensquilla:local(2.01G)已迁移到其他服务器,linuxserver/wireguard(166M)已废弃。两个都能安全删除。 -
未使用的虚拟环境(824M):
/root/.hermes/venv-crawl4ai占 824M,确认相关的服务不再使用后删除。
Tier 3 全部执行可释放约 6.3G。
全量效果
| 层级 | 释放空间 |
|---|---|
| Tier 1(零风险) | ~0.9G |
| Tier 2(低风险) | ~1.3G |
| Tier 3(中风险) | ~6.3G |
| 总计 | ~8.5G |
清理前 92%(~3.2G 可用),全量清理后能到 60-65%(~15G 可用)。
踩坑备忘
几个实际操作中遇到的问题,可能对其他做服务器清理的人也有用。
/tmp 不占磁盘空间。 ECS 的 /tmp 是 tmpfs,文件存在内存里。df -h /tmp 显示的空间消耗是内存使用量,不是磁盘。有些教程建议删 /tmp 释放磁盘,对 ECS 是无效操作。
Snap 包删除很慢。 如果系统里有 Snap 安装的 gnome/mesa/chromium 等桌面包,可以释放 3-5G。但 Snap 删除非常慢(尤其 chromium 需要 1-2 分钟),而且可能报 has "remove-snap" change in progress。需要用 snap changes 查看进度,等 Done 了再继续。
Docker 镜像的实际占用和列表大小不同。 docker system df 显示的是压缩后的镜像大小。SIZE 列是镜像的唯⼀层(不和其他镜像共享的部分),CONTENT SIZE 是你看到的大小。删除一个镜像释放的空间可能比预计小,因为层被其他镜像共享了。
# 查看每个镜像的真实磁盘占用
docker system df -v
生产服务器不要用 docker system prune -a。 这个命令会删除所有未运行的容器和未使用的镜像。听起来高效,但可能把一些不常用但需要的基础镜像也清理掉(比如 python:3.13-slim-bookworm,只在构建时用,平时处于”未使用”状态,被 prune 掉下次构建又要重新拉)。
总结
这次清理的核心方法就三条:
- 先量化再清理。 每次操作前记
df -h,操作完再记一次。不用感觉,用数字说话。 - 逐层 du 定位,不靠猜测。 从根目录开始,每次深入一层,找到最大目录后再往下拆。
- 按风险分级,逐步深入。 从缓存开始(零风险),到浏览器/构建缓存(低风险),到最后才动服务数据(中风险)。每步都有回退余地。
对于在云服务器上跑 AI 服务的开发者,日志和临时文件其实不是主要矛盾。真正吃空间的,是开发语言缓存、AI 服务的运行数据和 Docker 镜像。这几样东西加起来,40G 系统盘真不够用。