虚拟机挂载宿主机 vendor/ 目录是 i/o 卡顿主因,因 vboxsf/vmhgfs/9p 对小文件密集读写不友好,导致 stat/open 延迟达毫秒级、inode 耗尽报“no space left on device”,应禁用 vendor 挂载改用命名卷或 rsync 同步,并将缓存移至本地 ssd/tmpfs。

虚拟机里挂载宿主机 vendor/ 目录是 I/O 卡顿的直接原因,不是 Composer 本身慢,而是文件系统桥接层把每次 stat()、open() 都拖成毫秒级延迟。
为什么 vendor/ 挂载会导致超时或“No space left on device”
VirtualBox 的 vboxsf、VMware 的 vmhgfs 或 WSL 的 9p 对小文件密集读写极不友好。Composer 安装几百个包时,要反复检查 vendor/composer/installed.json、解压 ZIP、写入 .gitignore 等——这些操作在挂载卷上会触发大量跨系统元数据同步,strace 可见大量 openat() 延迟超过 50ms。错误提示 “No space left on device” 往往是 inode 耗尽(df -i 查),因为每个包版本都建独立子目录,而挂载卷对 inode 分配更保守。
- 禁用所有对
vendor/的volumes映射,包括-v $(pwd)/vendor:/app/vendor这类显式挂载 - 改用命名卷:例如
docker run -v $(pwd):/app -v composer-vendor:/app/vendor image composer install - 若必须复用已安装的
vendor,用rsync -av --delete vendor/ container:/app/vendor替代实时挂载,单次同步比持续桥接快 3–5 倍
composer install 卡在 “Resolving dependencies” 怎么破
这不是网络问题,是 Composer 在挂载卷上反复扫描 vendor/ 下数千个 composer.json 文件做插件发现和平台校验。Vagrant 或 VirtualBox 环境下尤其明显,vendor/composer/installed.json 时间戳易失真,导致它误判需重载插件并递归遍历整个目录树。
- 加
--no-platform-check跳过 PHP 扩展/版本校验(开发环境安全) - 显式声明允许的插件,在项目根目录
composer.json中加:"config": {"allow-plugins": {"phpstan/phpstan-nette": true}} - 运行前清缓存:
composer clear-cache,否则旧缓存里残留的 symlink 路径会引发重复解析 - 避免在共享目录中执行
composer update;可设COMPOSER_VENDOR_DIR=/home/vagrant/vendor把vendor移到虚拟机本地路径再安装
缓存路径落在挂载卷上会放大 I/O 瓶颈
Composer 默认缓存(~/.composer/cache/)若在宿主机机械硬盘或加密卷上,解压 ZIP 包前的校验阶段就会卡住。你看到的 “Extracting archive” 耗时 30 秒以上,大概率是缓存目录 I/O 不达标,而非网络下载慢。
- 查当前缓存位置:
composer config -g cache-dir - 迁移到虚拟机本地 SSD 或 tmpfs:
composer config -g cache-dir /mnt/ssd/composer-cache - Linux 下临时用内存盘:
sudo mount -t tmpfs -o size=2G tmpfs /mnt/ramdisk,再设为cache-dir - 别设成
/tmp,某些系统会定期清理,导致缓存反复重建
真正拖慢你的,从来不是 Composer 的算法,而是它在错误的文件系统上打开又关闭同一个文件 173 次——而这 173 次,全被虚拟机桥接层记在了账上。











