VPSSPark 博客
← 返回开发日记

服务器磁盘空间满了?一键清理常用缓存目录的脚本

机房手记 · 2026.07.23 · 约 11 分钟阅读

常见搜索:服务器磁盘满了 · Linux 清理磁盘 · VPS 磁盘空间 · 一键清理缓存脚本 (Docker · journal · apt)

机房机柜与服务器线缆——Linux VPS 磁盘空间与运维清理场景
磁盘告警往往是日志、容器层和包管理缓存日积月累;先诊断再脚本清理,比慌乱 rm 可靠得多。

凌晨三点,监控告警把值班手机震醒:/ 分区使用率 98%,MySQL 写不进 binlog,CI 部署在 docker pull 阶段直接报 no space left on device。我们连上机器跑 df -h,根分区只剩 412MB——不是突然被黑客塞了木马,而是三个月没人管的日志、Docker 层、apt 缓存和 journal慢慢把 40GB 小盘吃光了。

这类故障在中小 VPS 上极其常见:套餐磁盘不大,业务却 7×24 跑容器、拉镜像、打日志。手动 rm -rf 既慢又容易误删;更靠谱的做法是先定位大户,再用脚本批量清理「可再生」目录。本文把我们生产环境里反复用过的一键清理脚本整理成可复制版本,并标明哪些操作安全、哪些需要二次确认。

前提:你已有 SSH 登录权限和 sudo。若此刻已经连不上(例如 SSH 密钥写不进去),请先参考 Linux 服务器 SSH 连接被拒排查指南,确认是磁盘满导致还是网络/防火墙问题。磁盘救回来之前,别急着改 UFW 规则——先把空间腾出来,服务才能正常写日志。

5 分钟
定位 + 安全清理
8+
常见缓存目录
1 条
可复制清理脚本

磁盘满了,你会先看到什么?

Linux 在根分区写满时,表现往往很「玄学」:SSH 还能登录,但 vim 保存不了、apt install 失败、Docker 容器起不来、Nginx 返回 500 且 error.log 不再增长。MySQL / PostgreSQL 可能直接只读或崩溃;systemd 服务反复 restart,因为无法创建 pid 文件或写 socket。

第一步永远是看挂载点,而不是猜哪个目录「看起来大」:

快速诊断
# 各分区剩余空间
                df -hT

                # 根目录下一层谁最大(可能较慢)
                sudo du -xh --max-depth=1 / 2>/dev/null | sort -hr | head -20

                #  inode 用尽也会「假满」
                df -ih

du 在文件特别多时会扫很久;若机器已经卡死,可只对可疑路径点查,例如 sudo du -sh /var/lib/docker /var/log /var/cache。官方 du(1) 手册-x(不跨文件系统)和 --apparent-size 有详细说明——跨盘挂载时别被 du 总数误导。

服务器磁盘清理四步流程:df 诊断、du 定位大户、脚本清理可再生缓存、df 验证并配置 logrotate
顺序建议:先诊断再清理;清理后立刻 df 验证,并把 logrotate / 定时任务补上,避免三个月后重演。

常见「吃盘」目录对照表

不同业务组合不同,但下面几类在 Ubuntu / Debian VPS 上出现频率最高。表里标注了是否适合脚本一键清——带「谨慎」的请先确认没有业务依赖再动。

路径 / 来源 典型体积 可否自动清 说明
/var/lib/docker 数 GB~数十 GB 部分可 悬空镜像、停止的容器、未用 volume;运行中容器的数据卷勿删
/var/log/journal 1~10+ GB systemd 日志默认无上限时膨胀极快
/var/log/*.log 数百 MB~GB 谨慎 可 truncate 或 logrotate;直接 rm 可能导致进程仍占 inode
/var/cache/apt 数百 MB~数 GB apt-get clean 安全,只删已下载 deb 包
/tmp/var/tmp 不定 部分可 删 7 天未访问文件;注意是否有程序把临时上传放这里
Nginx proxy_cache 数 GB 缓存可重建;若你按我们 Nginx 反向代理调优 配了 cache,清完会短暂 MISS
旧内核 /boot 数百 MB apt autoremove --purge 删旧 kernel,保留当前与上一个
core dump、崩溃转储 不定 /var/crash、应用目录下的 core.*
先排除「真数据」
/home/var/lib/mysql、对象存储挂载点或备份目录最大,脚本清缓存帮不上忙——需要归档、扩容或迁走冷数据。清理只能回收「可再生」空间,不能代替容量规划。

一键清理脚本(可复制)

下面脚本默认干跑(dry-run):只打印将释放的空间与将执行的命令,加 --apply 才真正删除。建议先 dry-run,确认输出合理后再 apply。脚本按模块拆分,你可以注释掉不需要的部分(例如机器没装 Docker 就跳过 Docker 段)。

disk-cleanup.sh — 保存为 /usr/local/sbin/disk-cleanup.sh
#!/usr/bin/env bash
                # 服务器磁盘一键清理 — 仅处理可再生缓存
                # 用法: sudo ./disk-cleanup.sh          # 预览
                #       sudo ./disk-cleanup.sh --apply  # 执行
                set -euo pipefail

                APPLY=false
                [[ "${1:-}" == "--apply" ]] && APPLY=true

                log() { echo "[$(date '+%F %T')] $*"; }
                run() {
                  if $APPLY; then
                    log "EXEC: $*"
                    eval "$@"
                  else
                    log "DRY-RUN: $*"
                  fi
                }

                before=$(df -h / | awk 'NR==2 {print $3 " used, avail " $4}')
                log "Before: $before"

                # 1. apt 缓存
                if command -v apt-get >/dev/null; then
                  run "apt-get clean -y"
                  run "apt-get autoremove -y --purge"
                fi

                # 2. systemd journal — 保留最近 7 天或 500MB
                if command -v journalctl >/dev/null; then
                  run "journalctl --vacuum-time=7d"
                  run "journalctl --vacuum-size=500M"
                fi

                # 3. Docker 未使用资源(不含命名 volume 内业务数据)
                if command -v docker >/dev/null && docker info >/dev/null 2>&1; then
                  run "docker system prune -af --filter 'until=168h'"
                  run "docker builder prune -af --filter 'until=168h'"
                fi

                # 4. 临时目录 — 7 天未访问
                run "find /tmp /var/tmp -type f -atime +7 -print 2>/dev/null | head -20"
                if $APPLY; then
                  find /tmp /var/tmp -type f -atime +7 -delete 2>/dev/null || true
                fi

                # 5. Nginx proxy_cache(按你的 cache_path 修改)
                NGINX_CACHE="/var/cache/nginx"
                if [[ -d "$NGINX_CACHE" ]]; then
                  run "du -sh '$NGINX_CACHE'"
                  run "find '$NGINX_CACHE' -type f -delete 2>/dev/null || true"
                fi

                # 6. 崩溃转储
                [[ -d /var/crash ]] && run "rm -rf /var/crash/*"

                # 7. pip / npm 缓存(若存在)
                [[ -d /root/.cache/pip ]] && run "rm -rf /root/.cache/pip/*"
                for u in /home/*; do
                  [[ -d "$u/.npm" ]] && run "npm cache clean --force --cache '$u/.npm' 2>/dev/null || rm -rf '$u/.npm/_cacache'"
                done

                after=$(df -h / | awk 'NR==2 {print $3 " used, avail " $4}')
                log "After:  $after"
                $APPLY || log "预览模式结束。确认无误后: sudo $0 --apply"

赋予执行权限:sudo chmod 750 /usr/local/sbin/disk-cleanup.sh。第一次务必不加 --apply,把 DRY-RUN 输出存一份;若 Docker 段显示将删除大量镜像,确认没有「只剩本地、仓库已删」的唯一副本。

Docker prune 不是万能药
docker system prune -a 会删掉所有未使用的镜像,下次部署要重新 pull,在带宽紧张的 VPS 上可能反而拖慢恢复。更稳妥的是加 --filter until=168h(一周未用才删),或定期清理 dangling 镜像:docker image prune -f。详见 Docker 官方 pruning 文档

分模块说明:清什么、不清什么

journalctl--vacuum-time--vacuum-size 可组合使用,systemd 会按 journalctl 文档 规则裁剪二进制日志。若你希望永久限制体积,在 /etc/systemd/journald.conf 里设 SystemMaxUse=500Msystemctl restart systemd-journald

日志文件:对仍在被进程打开的大日志,用 truncate -s 0 /var/log/nginx/access.logrm 安全——进程仍持有 fd,rm 只删目录项,空间不会立刻释放。长期应配 logrotate,让 Nginx / 应用日志按天切割并保留 N 份。

aptapt-get clean 只清 /var/cache/apt/archivesautoremove --purge 会删旧内核和孤儿依赖。升级内核后建议保留「当前 + 上一版」两个 kernel,防止新内核启动失败时无法回退。

业务数据别碰/var/lib/mysql/var/lib/postgresql、Redis RDB、用户上传目录、备份挂载点——这些不在脚本默认范围内。若 du 显示它们最大,需要的是归档、扩容或迁冷存储,而不是清缓存。

清理之后:别让磁盘再次悄悄满

救急脚本跑完,根分区从 98% 降到 60% 只是开始。我们给中小 VPS 的最低配预防是三件事:

  • 监控阈值:云厂商或自建 Prometheus 在 80% 告警,85% 发短信——别等 95% 才有人看。
  • 每周 cron0 4 * * 0 root /usr/local/sbin/disk-cleanup.sh --apply >> /var/log/disk-cleanup.log 2>&1
  • journald + logrotate 上限:把「无限增长」改成「有顶的天花板」。

若跑 Docker Compose 栈,给 json-file 日志加 max-sizemax-file,否则单个容器的 stdout 就能把盘写满——这和清镜像一样重要,却常被忽略。

小盘 VPS 的容量心态
40GB 套餐跑 Web + DB + Docker 并不宽裕。把静态资源放对象存储或 CDN、数据库 binlog 定期归档、CI 构建放独立 Runner——比每个月手动救急更省心。磁盘是便宜资源,但运维时间不是。

上线前检查清单

把下面几条抄进你的运维笔记,下次告警来时按顺序打勾:

  • df -hTdf -ih — 确认是空间满还是 inode 满
  • du -sh 点查 docker、journal、log、cache 目录
  • 脚本 dry-run → 人工扫一眼 → --apply
  • 清理后 df -h 验证,并抽查核心服务(DB、Nginx、Docker)是否正常
  • 补 journald 限制、logrotate、cron 与 80% 告警

磁盘满从来不是「删几个文件」就结束的运维事件,而是一次容量与日志策略的体检。脚本负责把你在凌晨三点的手速从「慌乱 rm」拉回到「可重复的标准流程」——剩下的,是把预防补上,让告警少响几次。

开发构建占满磁盘?考虑分工部署

若你的 VPS 既要跑生产服务,又要本地 xcodebuild、Docker 多层构建或 Ollama 模型缓存,小盘很容易在编译周被 DerivedData 和镜像层挤爆。更稳妥的做法是生产 VPS 保持精简,把重构建迁到专用环境——例如云端 Mac 跑 iOS 出包、独立 Runner 跑 CI,生产机只拉最终产物。

Mac mini M4 凭借统一内存与低功耗,适合作为「只干构建、不扛 7×24 业务流量」的节点;与 Linux VPS 分工后,生产盘只留运行时数据,编译缓存不再和生产日志抢同一块 SSD。

如果你正在规划「生产机瘦身 + 构建环境分离」,可以先把重活迁到云端 Mac,让 VPS 回归轻量运维——了解 VPSSpark 套餐,少在凌晨三点和 df -h 搏斗。

限时特惠

构建占满磁盘?把重活迁出生产 VPS

云 Mac 跑编译出包 · Linux VPS 专注运行时 · 分工少救急

返回首页
限时优惠 点击查看套餐