Composer install报错mkdir(): Permission denied是因当前用户对vendor/或~/.composer/cache等目录无写入权限,需检查并修复对应路径权限,而非Composer本身故障。

composer install 报错 mkdir(): Permission denied
这是最常见的权限问题:Composer 尝试在 vendor/ 或缓存目录(如 ~/.composer/cache/)里建目录,但当前用户没写入权限。不是 Composer 本身坏了,是它被卡在了系统级文件操作上。
- 先确认报错路径——看错误信息末尾的
mkdir(): Permission denied in ...后面跟的到底是哪个路径,常见的是vendor/、~/.composer/cache/或项目根下的composer.lock所在目录 - 别直接
sudo composer install:这会让vendor/下所有文件属主变成 root,后续php artisan或本地开发服务器可能因权限不足失败 - 检查父目录权限:
ls -ld vendor/(如果已存在)或ls -ld .(当前项目目录),确保当前用户对该项目目录有rwx权限 - 临时修复可运行:
chmod u+rwx .(仅限当前项目目录,非全局);若vendor/已被 root 占用,先sudo rm -rf vendor/再普通用户重装
Linux/macOS 下 ~/.composer/cache 权限混乱
Composer 默认把包缓存放在用户家目录下,但有时该目录被 root 创建过(比如曾用 sudo composer),导致普通用户无法写入,后续所有命令都卡在这儿。
- 运行
ls -la ~/.composer/,重点看cache/目录的 owner 和权限;如果显示root root或权限不含w,就是它了 - 修复命令:
sudo chown -R $USER:$USER ~/.composer/cache(macOS/Linux 通用);完成后执行composer clear-cache验证是否成功 - 不建议删整个
~/.composer/:里面还有auth.json(含私有仓库 token)和配置,删了要重配 - 如果公司环境用统一镜像源,注意
~/.composer/config.json里的repositories设置是否被覆盖,权限修好后可composer config -g repo.packagist composer https://packagist.phpcomposer.com补回(按实际镜像地址)
Windows WSL 中 /mnt/c/ 下项目执行 composer install 失败
在 WSL 里访问 Windows 分区(如 /mnt/c/Users/name/project)时,Composer 创建 vendor/ 会触发 Windows 文件系统权限模型,常报 mkdir(): Permission denied 或卡住不动。
- 根本原因:WSL 对
/mnt/c/的挂载默认启用 metadata,但 Windows NTFS 不支持 Linux uid/gid,导致 chmod/chown 失效,Composer 内部调用mkdir时校验失败 - 最稳解法:把项目移到 WSL 原生文件系统,比如
~/projects/myapp,再运行composer install - 临时绕过(不推荐长期用):启动 WSL 时加参数禁用 metadata,编辑
/etc/wsl.conf加入:[automount]\noptions = "metadata,umask=22,fmask=11"
,然后wsl --shutdown重启 - 别信“在 Windows 里右键属性 → 解除锁定”:这对 WSL 底层权限无效,纯属浪费时间
CI/CD 流水线中 composer install 权限失败(GitHub Actions/GitLab CI)
流水线里报 Permission denied 多半不是真缺权限,而是工作目录未正确初始化,或缓存策略冲突。
- GitHub Actions 默认工作目录是
/home/runner/work/repo-name/repo-name,确保你的composer install步骤前有run: pwd && ls -la确认路径正确 - GitLab CI 若用了
cache:且 key 包含$CI_COMMIT_REF_SLUG,但缓存内容损坏(比如某次用 root 构建残留),会导致后续 job 解压失败;可加composer clear-cache在 install 前清理 - 避免在 CI 中用
--no-interaction --no-progress掩盖真实错误;去掉这两个参数跑一次,能看到具体卡在哪步(比如下载 zip 包时 403,其实是 token 过期) - Docker 场景下,如果 base image 是
php:alpine,确认已装curl和unzip(Composer 默认用 zip 安装包);否则会 fallback 到 tar,但某些 alpine 镜像没tar命令,报错却只显示权限问题
权限问题从来不是 Composer 的 bug,而是它忠实地把操作系统拒绝操作的结果抛了出来。真正麻烦的往往不是报错本身,是错误路径指向了一个你没意识到被其他流程污染过的目录——比如 CI 缓存、WSL 挂载点、或某次手抖的 sudo。










