根本原因是多用户环境下UID/GID不匹配导致操作系统拒绝写入,应删除vendor/和composer.lock后由当前用户重装,而非修补权限。

为什么多用户环境下 vendor 目录常报 Permission denied
根本不是 Composer “处理”了权限冲突,而是它根本不检查权限——composer install 只管按 composer.lock 把文件写进 vendor/,一旦操作系统拒绝写入,就直接抛出 file_put_contents(): Permission denied 或 mkdir(): Permission denied。多用户环境(如 CI/CD 共享构建机、Docker 多人协作、WSL 挂载 Windows 目录)下最常见的是:上一个用户用 UID 1001 创建了 vendor/,当前用户 UID 是 1002,连读都可能被拒。
如何快速判断是不是 UID/GID 不匹配
别猜路径或 chmod,先确认归属关系:
- 运行
ls -ld vendor/,看输出里 owner 是不是当前用户名(或 UID) - 运行
id -u和id -g,对比vendor/的 UID/GID 是否一致 - 在 Docker 中,还要进容器执行
docker-compose exec php id,确认容器内 UID 和宿主机是否对齐
若不一致,chmod -R 755 vendor/ 没用,因为 Linux 权限模型认 UID 不认用户名;sudo chown -R $USER:$USER vendor/ 也危险——如果 vendor/bin 里有软链到全局 bin,会断掉。
安全可靠的修复方式(不污染状态)
真正可重现、不埋雷的做法是“重来”,而不是“修补”:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 删干净:
rm -rf vendor/ composer.lock - 确保当前用户对项目根目录有完整读写权:
chmod u+rwX .(注意大写 X,只对目录和已有执行位的文件加 x) - 重装:
composer install—— 这次所有文件都由当前 UID 创建 - CI/CD 流水线中,务必在
composer install前加rm -rf vendor/,避免继承上一轮残留权限
不要用 sudo composer install,否则 vendor/ 归属变成 root,下次普通用户操作全卡死;也不要用 --ignore-platform-reqs,它完全不碰文件系统权限逻辑。
Docker 和 WSL 下必须绕开的坑
这些环境的权限问题本质是跨系统抽象失败,硬改权限只是临时止痛:
- WSL:避免在
/mnt/c/下跑composer install;把项目移到~/projects/(WSL 原生文件系统),并确认/etc/wsl.conf含metadata=true - Docker:不要用 volume bind mount 宿主机代码目录后在容器外执行
composer install;应在Dockerfile中COPY composer.json .后RUN composer install - docker-compose:通过
.env注入UID=$(id -u)和GID=$(id -g),并在php.dockerfile中用它们创建用户,而非硬编码 1000
最容易被忽略的一点:错误信息里写的失败路径(比如 ~/.composer/cache/)可能才是真正的权限瓶颈,vendor/ 只是连锁反应的终点。查错时得顺着 strace 或错误栈往回追,不能只盯着报错行。

















