Composer清理磁盘空间需重点清理/tmp下composer_.zip及composer_archive_临时目录,因clear-cache仅清~/.composer/cache;不清理会导致inode耗尽。

Composer 在 Linux 服务器上跑完 install 或 update 后,真正该清理的临时文件往往不在 vendor/ 或 ~/.composer/cache/,而是在系统临时目录(sys_get_temp_dir() 返回的位置,通常是 /tmp)里堆积的 composer_*.zip、解压中间目录和锁文件——这些不清理,df -i 很快就报 inode 耗尽。
为什么 composer clear-cache 清不完磁盘空间?
composer clear-cache 只清 ~/.composer/cache/ 下的 files/、vcs/、repo/,但 Composer 解压 ZIP 包、生成 autoloader、运行脚本时大量使用 /tmp,产生的 composer_*.zip 和随机命名的临时目录(如 /tmp/composer_archive_XXXXXX)完全不受该命令影响。
- 现象:执行
composer clear-cache后du -sh ~/.composer/cache显示已空,但df -h /tmp或df -i /tmp仍告警 - 验证方式:
find /tmp -name "composer_*" -type f -mtime +1 | head -20,大概率能列出一堆残留 ZIP - 风险点:
/tmp通常挂载在/分区,inode 耗尽会导致整个系统无法创建新文件(包括 PHP session、log 写入、甚至 SSH 登录)
如何安全清理 /tmp 下的 Composer 临时文件?
不能无差别 rm -rf /tmp/*——会误删其他进程正在用的临时文件。应只清理明确由 Composer 创建、且已闲置的条目。
- 优先用
find按名+时间过滤:find /tmp -name "composer_*" -type f -mmin +30 -delete(30 分钟未访问的 ZIP 文件) - 补充清理临时目录:
find /tmp -name "composer_archive_*" -type d -mmin +30 -empty -delete(空的、超时的解压目录) - 如果项目用了自定义
sys_get_temp_dir()(比如通过COMPOSER_HOME或PHP_INI_SCAN_DIR修改),先确认路径:php -r "echo sys_get_temp_dir();" - 避免权限问题:用部署用户执行(不要
sudo),否则可能留下 root 所有、普通用户无法再写的残留
怎样让清理动作自动嵌入部署流程?
把清理逻辑写进 composer.json 的 post-install-cmd 是常见做法,但要注意:这个钩子运行时,/tmp 的清理必须由系统级命令完成,不能依赖 PHP 函数(因为 sys_get_temp_dir() 可能被框架重写)。
- 推荐写法(Linux):
"post-install-cmd": ["find /tmp -name 'composer_*' -mmin +30 -delete 2>/dev/null || true"] - 更稳妥的方式是抽成独立脚本,例如
bin/clean-composer-tmp,内容为:#!/bin/bash find /tmp -name "composer_*" -mmin +30 -delete 2>/dev/null find /tmp -name "composer_archive_*" -type d -mmin +30 -empty -delete 2>/dev/null
然后在scripts中调用:"post-install-cmd": ["bash bin/clean-composer-tmp"] - 不要在钩子里加
rm -rf /tmp或tmpwatch类全局工具——它们不属于 Composer 生态,且行为不可控
CI/CD 环境下特别要注意的坑
GitHub Actions、Jenkins 等平台默认复用 /tmp,多个 Job 并发运行 composer install 时,/tmp 里的 Composer 临时文件可能互相覆盖或锁定,导致 Could not delete 报错或 ZIP 校验失败。
- 根本解法是隔离临时目录:在 CI 配置中设置
COMPOSER_CACHE_DIR和COMPOSER_HOME到工作区独占路径,同时用export TMPDIR="${PWD}/.tmp"强制 Composer 使用项目级临时目录 - 验证是否生效:
php -r "echo sys_get_temp_dir();"输出应为你的.tmp路径,而非/tmp - 清理动作也得跟着改:
find "${PWD}/.tmp" -name "composer_*" -delete,避免污染系统/tmp
最常被忽略的是:即使你每天 clear-cache,只要没碰 /tmp,inode 就一直在涨;而 df -i 不像 df -h 那样常被监控,等发现时往往已经连 ls 都卡住。











