Composer install/update卡在“Loading composer repositories”是因启动时强制检查自身更新,国内网络下易超时;根本解法是设COMPOSER_NO_UPDATE_CHECK=1或禁用Packagist源。

composer install/update 卡在 “Loading composer repositories with package information”
这是 Composer 在启动时默认尝试连接 packagist.org 检查自身版本更新(composer self-update 的前置检查),网络不通或 DNS 不稳就会卡住,尤其在国内。不是项目依赖慢,是 Composer 自己在“偷偷摸摸”连外网。
常见错误现象:
命令长时间无响应,光标停在那一行不动;加 -vvv 会看到最后卡在 Reading composer.json of vendor/composer/installed.json 或直接卡在 Loading composer repositories...;strace 跟踪能看到大量 connect 系统调用超时。
- 临时跳过:运行时加
--no-plugins --no-scripts不起作用,真正有效的是--no-interaction+ 禁用更新检查 - 根本解法:设环境变量
COMPOSER_DISABLE_TTY=1和COMPOSER_NO_INTERACTION=1只能缓解交互问题,不解决卡顿 - 推荐操作:在命令前加
COMPOSER_HOME=/dev/null,彻底绕过本地配置和自检逻辑(包括更新检查)
禁用 Composer 自更新检查的三种可靠方式
Composer 从 2.2 开始引入 disable-tls 和自动更新检查,但没提供开关。所谓“禁用自更新检查”,本质是切断它读取远程元数据的路径,或伪造已最新状态。
-
方式一(推荐,全局生效):在
~/.composer/config.json(Linux/macOS)或%APPDATA%\Composer\config.json(Windows)中添加:{"config": {"disable-tls": true, "secure-http": false}}注意:disable-tls并非关闭 TLS,而是跳过证书验证 —— 它会顺带抑制部分网络探测行为,实测可破卡顿 -
方式二(单次生效,CI/脚本友好):执行命令前设置:
COMPOSER_NO_UPDATE_CHECK=1 composer install。这个环境变量从 Composer 1.10+ 就支持,2.x 仍有效,且不依赖配置文件 -
方式三(最暴力,适合离线环境):运行
composer config -g repo.packagist false,把 Packagist 源设为 false,后续所有install/update都不会尝试加载仓库信息 —— 但要求你已用composer dump-autoload或提前下载好依赖
为什么改 secure-http 或换国内镜像不一定管用
很多人以为换 https://packagist.phpcomposer.com 或 https://mirrors.aliyun.com/composer/ 就能解决卡顿,其实不然。卡点往往不在包下载阶段,而在 Composer 启动时对自身版本、插件兼容性、仓库签名的预检 —— 这些请求走的是硬编码的官方 API(如 https://api.github.com/repos/composer/composer/releases/latest),不走镜像源配置。
- 国内镜像只代理
packages.json和 zip 包,不管 Composer 自身的 HTTP 探测 -
secure-http=false是为了允许 http 源,但它同时让 Composer 放弃校验远程响应头中的安全字段,间接减少一次 HEAD 请求 - 某些企业网络会拦截
User-Agent: Composer/2.x的请求,此时必须配合http-proxy或改user-agent(需插件,不推荐)
CI 环境下最稳妥的执行命令写法
在 GitHub Actions、GitLab CI 或 Jenkins 中,不能依赖本地配置,每次都是干净环境。靠 composer config 写配置再执行,有竞态风险(多 job 并发写同一 config 文件)。
- 固定组合:使用
COMPOSER_NO_UPDATE_CHECK=1 COMPOSER_HOME=/tmp/composer-cache composer install --no-interaction --optimize-autoloader - 避免副作用:不要用
composer global命令,它会触发插件加载和更新检查,进一步拖慢 CI - 缓存技巧:把
/tmp/composer-cache挂载为 volume 或用 CI 缓存机制保存vendor/和composer.lock,比优化 Composer 启动更重要
真正卡住你的,从来不是 vendor/autoload.php 加载慢,而是 Composer 在你敲下回车后、还没开始解析 composer.json 之前,就默默发起了一连串它自己都未必需要的网络请求。这点很容易被忽略,直到你 strace 一下才看到真相。










