真正原因是~/.composer/cache目录或其子目录被root占有,导致临时文件创建失败;应执行sudo chown -R $USER:$USER ~/.composer/cache修复所有权,而非chmod。

composer写入临时文件失败的真正原因不是/tmp权限低
报错里出现 file_put_contents(/tmp/composer_*.php) 或 Failed to write cache file ~/.composer/cache/...,别急着 chmod /tmp,95% 是 Composer 的全局缓存目录(~/.composer/cache)或其子目录被 root 占有,导致临时文件创建时因父目录属主不匹配而失败。Linux 下,普通用户无法在 root 所有目录下创建文件,哪怕 /tmp 本身是 1777。
快速确认:ls -ld ~/.composer/cachels -ld $(composer config --global cache-dir)
如果第三列显示 root,就坐实了归属污染。
chown 是唯一有效修复方式,别碰 chmod -R 777
临时文件写入失败本质是所有权错配,不是权限位不足。chmod 只控制“能不能读写”,chown 才决定“这东西归不归你”。用 chmod -R 777 不但无效,还会触发 Git 报 ownership changed、CI 拒绝构建、安全扫描告警。
- 修复全局缓存目录:
sudo chown -R $USER:$USER ~/.composer/cache - 连带修复整个全局配置目录(更彻底):
sudo chown -R $USER:$USER ~/.composer - 如果
composer config --global home输出的是/root/.composer,说明环境已被全局污染,必须重设:composer config --global home "$HOME/.composer"
用户组调整只在特定场景有用,别盲目加 docker 组
普通 Composer 使用完全不需要改用户组。只有两类情况才涉及组权限:
-
Docker 场景:你用
docker run启动容器执行 composer,并挂载了宿主机项目目录。此时若宿主机 UID=1000,容器内默认以 UID=0(root)运行,会导致写入失败。解决方式不是加组,而是对齐 UID:docker run -u $(id -u):$(id -g) ... -
CI 流水线(如 GitHub Actions):runner 用户(如
runner)无权写入系统级路径。这时应避免修改用户组,而是显式指定可写缓存路径:COMPOSER_CACHE_DIR="$PWD/.composer-cache" composer install,并提前mkdir -p .composer-cache && chmod 700 .composer-cache
把当前用户加进 docker 组(sudo usermod -aG docker $USER)只解决 docker 命令本身权限问题,和 Composer 写临时文件完全无关。
Windows / WSL 下的隐性陷阱
WSL 中若项目放在 /mnt/c/ 下,Linux 权限模型失效,chown 和 chmod 不生效,file_put_contents 会因 Windows ACL 拒绝写入。这不是 Composer 的错,而是跨系统挂载限制。
- 立即迁移项目到 WSL 原生路径(如
~/projects/myapp) - 确认
/etc/wsl.conf包含[automount] options="metadata",否则权限操作全无效 - Git Bash 下遇到
Access is denied,优先检查 Windows Defender 实时防护是否拦截了临时 PHP 文件生成
嵌套污染最易被忽略:一次 sudo composer install 可能让 ~/.composer/cache/repo/https---packagist.org/ 下某层子目录属主变成 root,ls -la 才能发现。这种情况下 chown -R 仍有效,但删掉整个 ~/.composer/cache 后重来往往更快。


















