Composer报“No space left on device”常因系统临时目录(sys_get_temp_dir())空间不足所致,该目录可能位于小容量分区,需用df -h或dir检查;可通过设置TMPDIR环境变量切换至大空间目录,并清理临时路径下composer-、php、zip*等文件。

临时目录空间不足导致 Composer 报错 "failed to write" 或 "No space left on device"
Composer 在解压 ZIP、生成 autoload、运行脚本时,重度依赖系统临时目录(sys_get_temp_dir() 返回的路径),而该目录常被忽略——它可能位于小容量分区(如 macOS 的 /var/folders、Windows 的 C:\Users\XXX\AppData\Local\Temp),即使磁盘整体还有空间,这里满掉也会直接失败。
常见错误现象包括:
file_put_contents(/var/folders/xx/yy/zz.zip): failed to open stream: No space left on device-
Could not create cache directory ~/.composer/cache/...(但实际是临时目录先爆了) Failed to extract vendor/package: unable to create temporary file
验证方式很简单:
- 运行
php -r "echo sys_get_temp_dir();"查出实际路径 - 用
df -h /path/to/temp(Linux/macOS)或dir C:\Users\XXX\AppData\Local\Temp(Windows)看剩余空间 - 注意:某些 macOS 临时目录有硬性配额(如
diskutil apfs list可见“Size”与“Used”),不是普通 df 能反映的
检查系统级配额(尤其是 Linux 用户配额和 macOS APFS 预留空间)
“No space left on device” 不等于磁盘满了,更可能是用户配额(quota)或文件系统预留空间耗尽。Composer 进程若以某用户身份运行(比如 CI 中的 www-data 或 Docker 容器里的非 root 用户),该用户可能被设了磁盘配额限制。
排查步骤:
- Linux 下运行
quota -u $(whoami)—— 若输出 “disk quotas turned off”,说明没启用;若有数值且已接近 limit,则需联系管理员调整 - macOS 上 APFS 卷默认有“快照保留空间”和“本地时间机器缓存”,可用
tmutil localsnapshot和sudo tmutil thinlocalsnapshots / 9999999999 1清理(慎用) - Docker 容器中,临时目录常挂载自宿主机
/tmp,需同时检查宿主机/tmp是否被占满或启用了 tmpfs 且 size 设得太小(如tmpfs /tmp tmpfs defaults,size=512M)
如何安全更换 Composer 临时目录位置
不建议暴力清空系统 /tmp(可能影响其他进程),更稳妥的是让 Composer 显式使用另一个有足够空间的目录作为临时区。它本身不提供 --temp-dir 参数,但可通过环境变量控制:
- Linux/macOS:运行前设置
TMPDIR="/path/to/big-disk/tmp",例如TMPDIR="/data/tmp composer install - Windows CMD:
set TMPDIR=D:\big-tmp && composer install - PowerShell:
$env:TMPDIR="D:\big-tmp"; composer install - 务必确保新目录存在且当前用户有读写权限(
chmod 700 /data/tmp,避免被其他用户写入)
注意:TMPDIR 优先级高于 sys_get_temp_dir(),但不会影响 COMPOSER_HOME 或 cache-dir,它们仍按原配置走。
为什么清理 composer clear-cache 有时没用
因为 clear-cache 只清 cache-dir,而临时文件在 TMPDIR 或系统默认临时路径里,根本不在 Composer 自己管理范围内。这也是很多人执行完 clear-cache 还报错的原因。
真正要清理的,是:
- 手动删
$(php -r "echo sys_get_temp_dir();")下的composer-*、php*、zip*开头的临时文件 - Docker 场景下,检查容器内
/tmp是否被构建层残留文件塞满(docker system prune -a可能比单删更彻底) - CI 环境(如 GitHub Actions)中,
TMPDIR默认指向/home/runner/work/_temp,这个路径容易因并发 job 积累未清理的 zip 解压残骸
临时目录的问题最难复现也最容易被绕过——它不报具体路径,只抛泛泛的 I/O 错误;一旦发生,必须盯住 sys_get_temp_dir() 的实际值,而不是只查 ~/.composer 或项目根目录。











