根本原因是误用 sudo 导致 vendor/ 或 ~/.composer 目录归属 root,普通用户无权访问;应改回当前用户权限:sudo chown -r $user:$user vendor/ 和 $(composer config –global home)。

composer install 报错 “Permission denied” 在 vendor 目录
根本原因是 composer 试图写入当前用户无权修改的 vendor/ 或 composer.json 所在目录,常见于用 sudo composer install 初始化后残留的 root 所有者权限。
不要用 sudo 运行 composer —— 它不是系统级工具,而是项目级依赖管理器。一旦混用,vendor/ 下所有文件归 root,普通用户后续操作全卡住。
- 先确认问题:运行
ls -ld vendor/,若显示root在 owner 位置,就是它了 - 修复命令(假设项目在当前目录):
sudo chown -R $USER:$USER vendor/ - 顺手检查
composer.lock和vendor/是否同属一个用户:ls -l composer.lock vendor/
composer global require 权限失败:~/.composer 不可写
composer global 默认把全局包装进 ~/.composer/vendor/,但该目录可能被创建为 root 权限(比如某次误用 sudo composer global require),导致后续任何 global 操作都报 Permission denied。
关键是定位真实缓存路径:composer config --global home 输出的就是实际目录,不一定是 ~/.composer(新版 Composer 2+ 默认是 ~/.composer,但可被配置覆盖)。
- 查路径:
composer config --global home - 改所有权:
sudo chown -R $USER:$USER $(composer config --global home) - 验证是否生效:
composer global list应正常输出,而非报错
cache-dir 权限混乱导致 composer update 卡住或静默失败
Composer 缓存默认存在 ~/.composer/cache/,如果这里权限不对,composer update 可能跳过下载、复用损坏缓存,甚至不报错就退出——现象是依赖没更新、vendor/ 里版本旧,但控制台没提示。
缓存目录权限错误不会直接抛出 Permission denied,而是 silently skip write,结果不可靠。
- 查看当前缓存路径:
composer config --global cache-dir - 强制重设为用户可写路径(推荐):
composer config --global cache-dir ~/.composer/cache - 清空并重置:
composer clear-cache(这步必须在权限修复后执行,否则仍失败)
docker 中运行 composer install 权限错乱:容器内 user 和宿主机 UID 不匹配
在 Docker 里用 docker run -v $(pwd):/app php:8.2-cli composer install,如果镜像默认以 root 身份运行,生成的 vendor/ 就属于 root,回到宿主机就无法修改或 git 提交。
这不是 Composer 本身的问题,但它是生产中最常被忽略的权限根源。
- 构建时指定非 root 用户:
docker run -u $(id -u):$(id -g) -v $(pwd):/app php:8.2-cli composer install - 或者在
Dockerfile中提前建好非 root 用户,并USER切换过去再跑composer install - 避免在容器里用
sudo或--user root,除非你明确需要且已同步宿主机 UID
真正麻烦的从来不是“怎么修”,而是“谁动过这个目录”。只要出现一次 sudo composer,整个项目的权限上下文就变了,后续所有操作都在一个隐性故障态里运行。盯住 ls -l 输出里的 owner 字段,比看错误信息还管用。