答案是目录属主为root而非当前用户,需用sudo chown -r $user:$user修复vendor/、composer.lock或全局缓存目录归属,禁用chmod -r 777;根据报错路径定位问题目录,执行ls -ld确认属主,再针对性修复。

报 Permission denied 不是权限位不够,而是目录属主被设成了 root,当前用户没“拥有权”。直接修归属,别碰 chmod -R 777。
看报错路径,立刻定位问题目录
终端错误里带完整路径的那一行就是线索。比如:
-
file_put_contents(/home/alex/myapp/vendor/autoload.php): Permission denied→ 问题在vendor/ -
Could not write to /home/alex/myapp/composer.lock→ 问题在composer.lock -
Writing cache file ~/.composer/cache/repo/https---packagist.org/...→ 问题在全局缓存目录
别猜,执行这三行就能确认:
ls -ld vendor/ ls -ld composer.lock ls -ld $(composer config --global cache-dir)
只要任意一行第三列(属主)不是你的用户名(比如显示 root root),就是所有权错配。
用 chown 修复归属,不是 chmod
chmod 控制“能不能读写”,chown 才决定“这东西归不归你”。95% 的 Permission denied 是后者问题。
- 只修项目内:
sudo chown -R $USER:$USER vendor/ composer.lock - 修全局缓存:
sudo chown -R $USER:$USER $(composer config --global cache-dir) - 整个
~/.composer都被污染了:sudo chown -R $USER:$USER ~/.composer
sudo 这里只是临时提权跑 chown,不是让你去跑 sudo composer install——后者才是污染源头。
global require 找不到命令?查 COMPOSER_HOME 和 bin-dir
composer global require laravel/installer 成功但输 laravel 报 command not found,大概率是二进制文件装进了 /root/.composer/vendor/bin/,而你的 shell 根本找不到它。
- 查真实全局路径:
composer config --global home,如果输出是/root/.composer,说明环境已被污染 - 临时绕过:
COMPOSER_HOME=$HOME/.composer composer global require laravel/installer - 长期解法:删掉
/root/.composer(若存在),之后所有global命令都不加sudo - 确保命令可用:
composer config -g bin-dir ~/bin,再把~/bin加进$PATH
Docker、WSL 或 CI 环境下权限更隐蔽
这些场景的问题常不报在主流程里,但一样卡住:
- Docker 中容器以
root用户挂载宿主机目录 → 启动时加-u $(id -u):$(id -g),或 Dockerfile 里加USER 1001 - WSL 访问
/mnt/c/下的项目 → NTFS 不支持 uid/gid,chown失效;应把项目移到 WSL 原生路径(如~/projects)再运行 - CI 脚本失败但本地正常 → 检查 runner 用户是否和你一致,
composer config --global home是否指向了不可写路径(如/var/www/.composer)
真正麻烦的从来不是报错本身,而是权限问题常跨层存在——表现在 vendor/,根子可能在缓存路径、Docker 用户配置,甚至 WSL 挂载方式上。每次遇到,先用 ls -ld 看清哪个路径被拒,比盲目改权限管用得多。











