FDE 又不够了。这里的 FDE 指的是前端开发环境(Frontend Development Environment),不是 Android 全盘加密。前端工程师、全栈开发者、以及所有在本地同时维护多个项目的同学,大概率都经历过同一个场景:C 盘或者 Mac 的硬盘条突然变红,Docker 拉不动镜像,npm install 直接报 ENOSPC,日志文件刷得飞快。排查一圈之后发现,罪魁祸首不是代码本身,而是开发环境里的缓存、依赖和镜像把磁盘吃干净了。
这篇文章不聊岗位梗,只聊怎么把磁盘从爆满状态里救回来。核心内容包括:先用工具和命令快速定位空间占用大户,再按照项目依赖、包管理器缓存、Docker 镜像、系统日志四个维度分别清理,最后给出防止 FDE 再次爆满的长期策略。文章里所有命令都是通用方案,适用于 Windows、macOS 和 Linux,读者可以直接复制到自己的环境里验证。
如果你是那种本地装了一堆 node_modules、Docker 镜像、Electron 缓存,还顺便跑过几个开源 AI 模型的开发者,这篇文章建议直接收藏。下面进入正题。
1. 核心能力与磁盘占用来源速览
先给一张速览表,把 FDE 磁盘爆满最常见的几个来源、典型位置和处理方式列清楚。实际占用大小会因项目和系统差异很大,不要照搬数字,重点是知道去哪里找。
| 占用来源 | 常见位置 | 典型特征 | 清理手段 | 风险等级 |
|---|---|---|---|---|
| node_modules | 各项目根目录 | 单个几十 MB 到几 GB,项目越多越夸张 | 删除后重新 install | 低,可恢复 |
| pnpm/npm/yarn 缓存 | 用户目录下 .npm、.cache、Library/Caches | 常年累积,动辄 10 GB 以上 | 包管理器自带 clean/prune | 低,可恢复 |
| Docker 镜像与构建缓存 | Docker 数据目录,Linux 默认 /var/lib/docker | 镜像、悬空层、build cache 体积巨大 | docker system prune | 中,需确认镜像用途 |
| Docker 容器日志 | /var/lib/docker/containers/ | 高频服务日志能涨到几十 GB | 限制日志大小或清空 | 中,影响排障 |
| Electron/Chromium 缓存 | 用户缓存目录 | 多个 Electron 应用各占一份 | 直接删缓存目录 | 低 |
| 系统日志 | /var/log、C:\Windows\Temp、/tmp | 日志文件长期不轮转 | logrotate + 清理 | 低 |
| Git 对象历史 | 项目 .git 目录 | 大二进制文件提交后残留 | git gc / 重写历史 | 较高,需谨慎 |
| 本地模型下载缓存 | ~/.cache/huggingface、ComfyUI models 目录 | 大模型文件单文件数 GB | 按需保留或转移 | 较高,影响离线使用 |
从实际经验看,磁盘爆满通常不是某个单一原因,而是这几个来源叠加。定位的顺序应该是:先看整体磁盘分配,再逐层下钻到具体目录,最后判断哪些能删、哪些要迁移、哪些必须保留。
2. 适用场景与使用边界
这套排查与清理方案适合四类人:
- 本地同时维护多个前端项目的工程师,被 node_modules 和缓存折腾过;
- 使用 Docker 做本地联调或部署验证,镜像和构建缓存常年堆积;
- 电脑上装了 Electron 应用、浏览器多个 Profile,用户目录膨胀到无法忽略;
- 顺便玩本地 AI 工具或大模型,huggingface 缓存和 ComfyUI 模型文件体积巨大。
不适合的直接删除场景也要先说清楚。涉及生产服务器、数据库文件、私钥、证书、未提交的本地分支、依赖锁定文件不匹配等场景,不要照搬一键清理命令。清理 Docker 卷时尤其要谨慎,docker system prune -a --volumes会删除没有被容器使用的匿名卷,如果里面有本地数据库数据,删掉就很难恢复。
使用边界上还要注意数据安全和版权。本地可能有公司内部代码、客户资料、模型权重等敏感文件,清理前要确认归属。本文所有命令都建议先打印结果、再执行删除,而不是直接一条命令带走。
3. 环境准备与前置检查
清理磁盘不需要太复杂的准备,但需要确认三件事:当前磁盘状态、是否存在正在运行的服务、是否有需要备份的关键文件。
先看整体磁盘使用情况。Linux 和 macOS 系统使用 df 命令:
df -h输出里会看到/、/home、/Users等挂载点的使用率和剩余空间。如果使用率已经超过 85%,说明确实到了需要动手的时候。
Windows 可以在 PowerShell 里查看:
Get-PSDrive C | Select-Object Used,Free接下来确认 Docker 或者本地开发服务是否正在运行。清理 Docker 相关资源之前,先检查是否有正在使用的容器:
docker ps清理之前,建议对关键配置文件做一次备份。特别是package-lock.json、pnpm-lock.yaml、yarn.lock,以及 Docker Compose 的.env文件。这些文件体积小,但删错了会导致依赖无法锁定版本,或者服务配置丢失。
4. 第一步:定位磁盘空间占用大户
不要凭感觉删东西,先用工具找出真实的磁盘占用分布。
Linux 和 macOS 下最直接的方式是 ncdu。它是一个交互式磁盘分析工具,按目录大小从大到小展示,操作直观:
# macOS brew install ncdu # Ubuntu / Debian sudo apt install ncdu # 开始扫描当前目录 ncdu /扫描完成之后,用键盘方向键进入目录,按d删除目标目录,按q退出。ncdu 的优势是可以在交互界面里反复查看,不容易误删。
如果没有 ncdu,也可以用 du 和 sort 快速定位:
# 查看根目录下各目录占用,取前 20 sudo du -sh /* 2>/dev/null | sort -hr | head -20 # 查看当前项目里哪个目录最大 du -sh * 2>/dev/null | sort -hr | head -20Windows 用户建议使用 WizTree 或 TreeSize。这类工具以 NTFS 的 MFT 直接扫描,速度比 PowerShell 递归统计快很多,几秒钟就能看到整个磁盘的占用热力图。如果不想装图形工具,也可以直接在项目目录里用 PowerShell 统计:
Get-ChildItem -Directory | ForEach-Object { $size = (Get-ChildItem $_.FullName -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum [PSCustomObject]@{ Name = $_.Name; SizeMB = [math]::Round($size / 1MB, 2) } } | Sort-Object SizeMB -Descending | Select-Object -First 20定位的目标是找出占用最高的前三个目录,然后逐个判断是哪种类型:是 node_modules、是 Docker 数据目录、还是缓存目录。定位清楚之后,再进入对应的清理步骤。
5. 第二步:清理项目依赖与 node_modules
node_modules 是前端开发环境里最招人恨的目录之一。一个中等规模项目,依赖装完动辄 500 MB 到 2 GB。如果同时维护 10 个项目,就是 5 GB 起步,这还不包括 pnpm 的全局 store。
清理单个项目的 node_modules 不难。Linux 和 macOS 直接用 rm:
rm -rf node_modulesWindows 下 node_modules 经常出现路径过长导致删除失败的情况,可以先用 npx rimraf 处理:
npx rimraf node_modules删完之后重新安装依赖:
# npm npm install # pnpm pnpm install # yarn yarn这里要强调一下锁文件的作用。删除 node_modules 之前,必须确认项目根目录有package-lock.json、pnpm-lock.yaml或yarn.lock。有锁文件,重新安装后的依赖版本才是可控的;没有锁文件,重装之后依赖版本可能飘掉,导致项目跑不起来。
如果你用的是 pnpm,它还有个更隐蔽的磁盘占用点,就是全局 store。pnpm 会把所有依赖包的实体文件存储在 store 里,项目里的 node_modules 只是硬链接或符号链接。所以,即使你删了项目里的 node_modules,pnpm store 里的文件也还在。查看和清理方式:
# 查看 store 位置 pnpm store path # 删除 store 中未被项目引用的包 pnpm store prunepnpm store prune是安全的,它只会清理没有被任何项目引用的包。如果多个项目共用同一个 store,清理后需要重新安装依赖的项目会重新从网络下载缺失的包,但已存在的包仍然复用。
对于长期维护的项目,建议从 Yarn 或 npm 切换到 pnpm。pnpm 的依赖存储方式天然节省磁盘,同一个版本的依赖包在全局只保存一份。迁移方式不复杂,删除 node_modules 后导入锁文件即可:
pnpm import package-lock.json pnpm install6. 第三步:清理包管理器缓存与构建缓存
很多开发者的磁盘爆满问题,不只是 node_modules 导致的,更常见的是包管理器缓存和构建缓存长期不清理。
npm 的缓存存放在用户目录下的~/.npm,清理命令:
npm cache clean --forcepnpm 的缓存仓库回收:
pnpm store pruneyarn 经典版和 Berry 版的缓存清理命令不同:
# yarn 1.x yarn cache clean # yarn 2+/Berry yarn cache clean --all清理这些缓存不会影响项目运行,最多只是后续安装依赖时需要重新下载。代价是网络时间和带宽,风险很低。
如果本地使用 Vite、Webpack、Next.js 或 Vue CLI 构建项目,构建缓存也会占用不少空间。常见位置包括:
node_modules/.cache,Webpack 和 Vite 都会在这里写入缓存;~/.cache/next,Next.js 构建缓存;~/.cache/esbuild,esbuild 二进制和缓存;~/.cache/puppeteer、~/.cache/ms-playwright,自动化测试浏览器缓存。
这类缓存可以安全删除,删除后下次构建会重新生成。以 esbuild 为例,很多人不知道 esbuild 会在~/.cache/esbuild下保存二进制文件,清理命令:
rm -rf ~/.cache/esbuildElectron 应用的缓存也是个容易忽略的大头。Electron 基于 Chromium,每个应用在自己的用户数据目录下保存一份浏览器缓存。比如 VS Code、Slack、Discord 这些应用的缓存目录,可能各自占用几百 MB 到几个 GB。清理时需要先关闭应用,然后删除对应缓存目录:
# macOS 下 VS Code 缓存示例 rm -rf ~/Library/Caches/com.microsoft.VSCode # Linux 下 Electron 通用缓存位置 rm -rf ~/.cache/电子应用名Windows 下则位于%APPDATA%\应用名\Cache和%LOCALAPPDATA%\应用名\Cache。删除缓存不会影响账号登录和应用功能,但应用下次启动时会重新下载或生成缓存。
7. 第四步:Docker 镜像、容器与日志回收
如果你的开发环境里装了 Docker,磁盘占用一般不会小。Docker 的问题在于,它不只是存镜像,还会积累构建缓存、容器读写层、悬空镜像和日志文件。
先看 Docker 到底占了多少:
docker system df输出会显示镜像、容器、本地卷、构建缓存的占用汇总。如果BUILD CACHE一栏显示十几 GB,说明构建缓存已经成为主要占用源。
一键清理所有未使用的 Docker 资源:
# 清理悬空镜像、停止的容器、未使用的网络 docker system prune # 更激进:删除所有未被使用的镜像、构建缓存,以及未被容器使用的匿名卷 docker system prune -a --volumesdocker system prune -a --volumes要谨慎使用。它确实能释放大量空间,但会删除:
- 没有被任何容器使用的镜像;
- 所有构建缓存;
- 没有被容器引用的匿名卷。
如果你的本地数据库跑在 Docker 匿名卷里,执行这条命令会直接丢数据。更稳妥的方式是分步清理,先清构建缓存,再清悬空镜像,最后再决定是否清理卷:
# 清理构建缓存 docker builder prune -a # 清理悬空镜像 docker image prune -a # 查看卷占用,逐个确认 docker volume ls容器日志是另一个容易被忽略的大户。Docker 默认会把容器标准输出写到 json-file 日志文件里,而且默认不限制大小。长时间运行的容器,日志文件可能撑到几十 GB。查看单个容器日志文件大小:
# 找到日志文件位置 docker inspect --format='{{.LogPath}}' 容器名比较直接的方案是清空现有日志,然后配置全局日志上限。清空单个容器的日志:
# 以 root 身份执行,注意容器名需要替换 truncate -s 0 $(docker inspect --format='{{.LogPath}}' 容器名)更根本的解法是在/etc/docker/daemon.json里配置日志轮转:
{ "log-driver": "json-file", "log-opts": { "max-size": "50m", "max-file": "3" } }修改配置后需要重启 Docker 服务:
sudo systemctl restart docker这样配置之后,每个容器的日志单文件最大 50 MB,最多保留 3 个文件,可以有效防止日志文件无限膨胀。
8. 第五步:系统日志、临时文件与本地模型缓存
系统层面的临时文件和日志也是磁盘杀手,只是它们藏得比较深,平时不会特意去看。
Linux 系统日志默认位于/var/log。长期不清理的话,journald的日志能积累到好几个 GB。查看 systemd journal 占用:
journalctl --disk-usage限制 journal 大小,并清理旧日志:
# 限制 journal 最大占用 200 MB sudo journalctl --vacuum-size=200M # 永久配置 sudo mkdir -p /etc/systemd/journald.conf.d在/etc/systemd/journald.conf.d/size.conf中写入:
[Journal] SystemMaxUse=200M然后重启 journald:
sudo systemctl restart systemd-journald/tmp目录和用户临时目录也值得检查。Linux 下某些服务会往/tmp写入临时文件,如果服务没有自动清理,会一直堆积。重启系统会清空/tmp,但长期开机的开发机可能已经积累了数 GB 临时文件:
sudo du -sh /tmp 2>/dev/null如果本地部署过 AI 工具或大模型,还需要检查模型缓存目录。huggingface 的默认缓存在~/.cache/huggingface,ComfyUI、Stable Diffusion WebUI 的模型目录通常在项目目录或~/.cache下。大模型单文件动辄 2 GB 到 7 GB,模型多的话占用非常可观。
处理方式不是简单删除,而是考虑迁移。把模型目录移动到独立磁盘或外置 SSD,然后创建软链接指向原路径:
# 把模型目录移动到 /data/models mv ~/.cache/huggingface /data/models/huggingface # 创建软链接 ln -s /data/models/huggingface ~/.cache/huggingface这一步需要先关闭相关应用再操作,避免文件被占用导致移动失败。迁移后应用仍然显示模型在原位置,但实际存储在独立磁盘上,不会挤占系统盘空间。
9. 防止 FDE 再次爆满的长期策略
清理一次只能救急,防止再次爆满才是关键。长期策略可以从四个方向入手。
第一,统一依赖安装策略。新项目优先使用 pnpm,并开启全局 store 共享。团队协作时提交pnpm-lock.yaml,统一依赖版本。旧项目如果维护成本高,可以在 CI 里构建,本地只保留必要的依赖,而不是把所有项目都完整 install 一遍。
第二,给 Docker 设置资源上限。daemon.json里配置日志轮转后,还需要定期执行构建缓存清理。可以把清理命令写进每周计划任务,在低峰期自动执行:
0 3 * * 1 docker builder prune -a -f && docker image prune -a -f但要注意,这条 crontab 不会处理 Docker 卷,卷的清理仍然需要人工确认。
第三,建立磁盘告警。写一个简单的脚本,当磁盘使用率超过阈值时提醒自己。以 Linux 为例:
#!/usr/bin/env bash threshold=85 usage=$(df / | awk 'NR==2 {print $5}' | tr -d '%') if [ "$usage" -ge "$threshold" ]; then echo "[$(date)] 磁盘使用率 ${usage}%,请检查以下目录:" du -sh ~/.npm ~/.cache /var/lib/docker 2>/dev/null fi配合 crontab 每小时执行一次,或者在开发机启动时执行,能起到预警作用。Windows 下则可以用计划任务 + PowerShell 脚本实现类似效果,核心思路一致:占用率超过阈值就输出提示,而不是等到磁盘写满才发现。
第四,目录迁移。如果系统盘本身不大,建议把容易膨胀的目录整体迁移到数据盘。Windows 下可以把 npm 缓存、Docker 数据目录、用户下载目录迁移到 D 盘或外置 SSD。macOS 下可以把~/Library/Caches下的主要缓存目录改用软链接指向外部磁盘。迁移操作需要谨慎,涉及系统路径时先查文档,避免影响已有服务。
10. 常见问题与排查方法
清理过程中可能会遇到一些问题,下面按现象的维度做一张排查表。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 删除 node_modules 后项目跑不起来 | 缺少锁文件或依赖版本漂移 | 检查 package-lock.json 是否存在 | 用锁文件重新 install,或还原备份 |
| pnpm store prune 后依赖损坏 | 清理了仍被引用的包 | 检查 pnpm 的报错信息 | 重新执行 pnpm install 修复 |
| 清理 Docker 镜像后容器无法启动 | 容器的镜像被删除或 tag 丢失 | docker ps -a 查看容器状态 | 重新 docker-compose up 或 pull 镜像 |
| Docker 卷清理后数据丢失 | 匿名卷里有数据库数据 | 清理前未执行 docker volume ls 确认 | 从备份还原,或提前挂载命名卷 |
| 删除文件后磁盘空间没有释放 | 文件被进程占用,尤其 Docker 和日志进程 | lsof +L1 查看句柄 | 重启相关服务后再确认 |
| journalctl 清理后空间仍在涨 | journald 配置未持久化 | 查看 journald.conf 配置 | 修改配置并重启服务 |
| npm cache clean 后安装变慢 | 缓存被清空,需重新下载 | 安装日志显示从网络拉取 | 属于正常现象,可接受 |
| WizTree 扫描结果和系统显示不一致 | 权限或扫描模式问题 | 以管理员身份运行工具 | 重新扫描,或对比 df 输出 |
最值得注意的坑是“文件被占用导致空间不释放”。在 Linux 下,如果一个文件被进程打开,即使你删除了它,空间也要等进程关闭后才释放。如果删完文件发现磁盘占用没变,用下面命令查找被删除但仍然打开的文件:
lsof +L1找到对应的 PID 后,重启对应进程即可释放空间。Windows 环境下,被占用的文件通常会直接提示“操作无法完成”,需要先关闭相关程序,或者用 PowerShell 的 handle 工具定位占用进程。
11. 最佳实践与使用建议
结合前面所有清理方案,总结几条工程化的建议。
先做容量规划,再动手清理。不要在没有备份的情况下直接执行docker system prune -a --volumes或rm -rf node_modules,尤其是公司项目或重要数据目录。建议第一次清理时先做记录,把各目录清理前的体积写下来,清理后对比,这样能明确知道每个方案释放了多少空间。
清理命令从风险低的开始。推荐顺序是:包管理器缓存、构建缓存、node_modules、Docker 构建缓存、Docker 悬空镜像、系统日志,最后才是 Docker 卷和 git 历史。每执行一步,观察磁盘状态,确认没有副作用,再进行下一步。
模型文件、Docker 卷这类重要资源,优先考虑迁移而不是删除。迁移到独立磁盘后,既能保留资源,又不占系统盘空间。迁移前务必备份,迁移后验证路径是否生效。
批量任务或团队协作的场景中,要把依赖安装从本地搬到 CI。本地只需要一份最小的运行环境,开发验证尽量使用共享缓存。这样能从根本上减少每个开发者的磁盘压力。
最后,给开发机建立一种“每周一次清理”的习惯。可以不用每周都清理,但每周看一次磁盘使用率,发现增长趋势时再执行对应清理,总比磁盘爆满后紧急处理省事得多。
12. 总结与下一步
FDE 磁盘爆满的问题,本质上不是单一原因导致的,而是依赖目录、缓存、Docker 资源、系统日志和模型文件长期累积的结果。最优先要做的事,是先跑一遍磁盘分析工具,把最大的三个目录找出来,再根据类型决定清理还是迁移。
最容易踩的坑有两个:一是 Docker 卷清理携带数据丢失风险,二是文件被进程占用导致空间没有真正释放。前者靠清理前检查解决,后者靠 lsof 定位进程解决。
如果你现在磁盘还够用,建议先写一个磁盘告警脚本,把阈值设到 85%,然后再决定要不要主动清理。如果磁盘已经开始报警,按照第二节到第八节的顺序,从缓存和 node_modules 开始清,最后再处理 Docker 卷和模型文件。整套流程走完,磁盘至少能腾出一片不小的空间,也能让后续开发环境保持一个干净可控的状态。