根本原因是php无法写入系统临时目录(如/tmp),导致composer解压、缓存等操作失败;常见于/tmp权限错误、容器只读挂载、selinux拦截或php配置指向无效路径。

根本原因不是 Composer 本身出错,而是 PHP 写入系统临时目录(如 /tmp)失败,导致 Composer 在解压、缓存、生成 autoload 文件等环节卡住。
为什么 /tmp 权限会出问题
Composer 依赖 PHP 的 sys_get_temp_dir() 返回路径来存放临时文件(例如 zip 解压中间产物、phar 缓存等)。如果该路径不可写,就会报类似 failed to open stream: Permission denied 或 mkdir(): Permission denied 的错误,且通常不提示具体路径——容易误判为 vendor 目录权限问题。
- 常见于服务器被多人共用,
/tmp被其他用户或脚本意外清空/改权限 - 某些容器环境或 CI runner 中,
/tmp挂载为只读或大小受限 - SELinux 或 AppArmor 强制策略拦截了写入(CentOS/RHEL 环境尤其要注意)
- PHP 配置中
sys_temp_dir或upload_tmp_dir指向了一个不存在或无权限的自定义路径
确认 PHP 实际使用的临时目录
别猜,直接查:
php -r "echo sys_get_temp_dir();"
输出结果通常是 /tmp,但也可能是 /var/tmp、/home/username/tmp 等。接着检查该路径是否存在且可写:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 运行
ls -ld $(php -r "echo sys_get_temp_dir();"),确认输出中包含drwxrwxrwt(末尾t表示 sticky bit,正常) - 若权限不对(比如缺
w),或属主不是当前用户且不在可写组里,就需修复 - 若路径根本不存在,手动创建并设权:
mkdir -p /path/to/temp && chmod 1777 /path/to/temp(注意必须是1777,不是777)
清理 /tmp 并避免误删关键文件
直接 rm -rf /tmp/* 很危险——可能干掉正在运行的服务(如 systemd、MySQL 临时 socket)或其它用户的临时文件。稳妥做法是:
- 只清理 Composer 明确使用的子目录:
find /tmp -maxdepth 1 -name "composer-*.phar" -delete - 清理过期的 PHP session 或 upload 临时文件(如有):
find /tmp -name "sess_*" -mmin +60 -delete - 若确定是磁盘满导致写入失败,先用
df -h /tmp查空间,再用du -sh /tmp/* | sort -hr | head -10找大文件 - 不要对
/tmp做chmod 777——开放所有用户写入是严重安全隐患;chmod 1777才是标准做法(允许创建但不能删他人文件)
PHP 配置与容器/CI 场景的特殊处理
在 Docker、GitHub Actions、GitLab CI 等环境中,/tmp 可能被挂载为 tmpfs 或受限 volume,PHP 默认路径不一定可靠:
- 可在
php.ini中显式指定:sys_temp_dir = /tmp/php-tmp,然后mkdir -p /tmp/php-tmp && chmod 1777 /tmp/php-tmp - Dockerfile 中建议加一句:
RUN mkdir -p /tmp/php-tmp && chmod 1777 /tmp/php-tmp,并在启动时通过环境变量传给 PHP:PHP_INI_SCAN_DIR=/etc/php/conf.d:/tmp/php-tmp(视情况调整) - GitHub Actions 中,
actions/setup-php默认已处理,但如果自定义 runner,请确保/tmp是可写的 ext4 文件系统,而非 NFS 或 cifs
真正容易被忽略的是:即使 /tmp 权限正确,PHP 进程也可能因 open_basedir 限制而无法访问它。检查 php -i | grep open_basedir,若输出非 no value,需将临时目录加进白名单。










