根本原因是当前用户对vendor或~/.composer/cache无写权限,多因误用sudo导致属主变为root;应修复属主、改用用户可控的缓存目录(如~/composer-cache)、避免sudo及挂载vendor卷。

composer install 报错 “Permission denied” 在 vendor 目录
根本原因不是 Composer 本身有问题,而是当前用户对 vendor 目录或其子目录(尤其是 composer/cache)没有写权限。常见于用 sudo composer install 初始化过项目,导致部分文件属主变成 root,后续普通用户操作就卡住。
- 别再用
sudo composer install—— 这是绝大多数权限问题的起点 - 检查
vendor和~/.composer/cache的属主:ls -ld vendor ~/.composer/cache - 如果属主是
root,直接修复:sudo chown -R $USER:$USER vendor ~/.composer/cache - Windows WSL 用户注意:NTFS 挂载点可能默认禁用 chmod,需在
/etc/wsl.conf中启用metadata
修改 composer 缓存目录到用户有完全控制权的位置
默认缓存放在 ~/.composer/cache,但某些系统策略或容器环境会限制该路径写入。换一个明确属于当前用户的路径更稳妥,比如 ~/composer-cache。
- 设置新缓存路径:
composer config -g cache-dir ~/composer-cache - 确认生效:
composer config -g cache-dir应输出/home/yourname/composer-cache - 旧缓存可手动清理:
rm -rf ~/.composer/cache(设完新路径后才安全删) - 该配置写入全局
config.json,不影响单个项目,也无需每次重复执行
CI/CD 或 Docker 中 “Permission denied” 的典型表现和解法
在 GitHub Actions、GitLab CI 或自建 Docker 构建中,composer install 常因运行用户 UID 不匹配宿主机缓存目录权限而失败,错误信息里通常带 mkdir(): Permission denied 或写入 repo/ 子目录失败。
- Dockerfile 中避免用
root用户跑 composer:加USER 1001(或对应非 root UID) - 挂载缓存卷时指定 UID:
docker run -v $(pwd)/composer-cache:/home/app/.composer/cache:z -u 1001 … - GitHub Actions 推荐用官方 action:
php-actions/composer@v6,它自动处理用户和缓存权限 - 不要把
vendor目录挂载为 volume——它本就不该跨构建复用,反而引发权限混乱
为什么改缓存目录比硬调 chmod 更可靠
单纯 chmod -R 755 ~/.composer/cache 看似能过,但 Composer 内部会生成临时文件、锁文件、甚至嵌套很深的 hash 目录,有些路径仍可能因 umask 或父目录权限继承失败。而换目录+明确属主,是从源头切断权限污染链。
-
cache-dir是 Composer 官方支持的配置项,无兼容性风险 - 不同 PHP 版本、不同 Composer 大版本(1.x / 2.x)对该配置行为一致
- 多项目共用同一缓存时,新路径下所有子目录天然归属当前用户,不会出现“一半可写一半拒绝”
- 最常被忽略的一点:某些 IDE(如 PHPStorm)会后台调用 composer,它读的是全局配置,所以必须用
-g参数生效










