应同时设置process-timeout和http-basic-timeout:前者控制命令全流程总耗时(默认300秒),后者控制单次HTTPS请求全过程(默认60秒),二者独立生效,缺一不可;v2.2+必须用repositories.packagist.org配置镜像,且URL须以/结尾、type显式写composer。

Composer超时报错不是网络慢,而是默认超时值太低且配置没生效——process-timeout和http-basic-timeout必须同时设,缺一不可。
process-timeout 和 http-basic-timeout 到底管什么
这两个参数完全独立,各自控制不同阶段,只调一个等于白调:
-
process-timeout控制整个命令生命周期:从解析依赖、下载 ZIP、解压、执行 post-install-cmd 到生成 autoload files,全部加起来不能超时。默认 300 秒(5 分钟),大项目很容易卡在“Generating autoload files”前就中断 -
http-basic-timeout(Composer 2.2+)控制单次 HTTPS 请求全过程:DNS 解析 + TLS 握手 + 首字节等待 + body 下载。默认仅 60 秒,国内镜像首包延迟常超 100ms,极易触发cURL error 28 - 旧版用
http.timeout替代http-basic-timeout,但 v2.2+ 已不读取;http-basic-timeout是当前唯一有效项
全局配置怎么写才真正生效
全局配置写错位置、漏参数、没清缓存,都会导致“看似配了,实则无效”:
- 执行
composer config -g process-timeout 1800和composer config -g http-basic-timeout 300,两行都得跑 - 别用
sudo执行,否则写进/root/.composer/config.json,而普通用户运行composer global require读的是$HOME/.composer/config.json - PHP 若禁用了
putenv()(见php.ini中disable_functions),config -g会静默失败,建议改完后立刻验证:composer config -g process-timeout应输出1800 - 必须执行
composer clear-cache,否则旧的packages.json元数据还在本地,根本不会发新请求
为什么换源后还是连 packagist.org
镜像配置写错键名或格式,Composer 会静默忽略,日志里毫无提示:
- Composer 2.2+ 必须用
repositories.packagist.org,不是repo.packagist(后者是 v1 写法,v2.2+ 已废弃) - URL 必须以
/结尾:https://mirrors.aliyun.com/composer/✅,https://mirrors.aliyun.com/composer❌(少斜杠会拼出非法路径/composerpackages.json) - type 值必须显式写
"composer",不能省略,也不能拼错 - 验证是否生效:
composer config -g repositories.packagist.org应输出完整 JSON,如{"type": "composer", "url": "https://mirrors.aliyun.com/composer/"}
CI/CD 环境里 timeout 还是失效?检查这几点
CI 容器重启后配置丢失、工作目录不对、扩展缺失,比超时本身更常见:
- GitHub Actions 中,必须显式设置
working-directory: ${{ github.workspace }}或先run: cd ${{ github.workspace }},否则composer install在错误路径执行 - 必须提前安装 PHP 扩展:
ext-zip、ext-xml、ext-mbstring缺一个,composer install直接退出,不是超时 - 环境变量优先级最高:
COMPOSER_PROCESS_TIMEOUT=1200能覆盖插件和自定义 installer 启动的子进程,比config -g更可靠 - 私有 Git 包(如
git@github.com:user/repo)会绕过镜像直连,必须换成 HTTPS 地址,或配GIT_SSH_COMMAND
最易被忽略的是:process-timeout 设为 0 后仍失败,大概率是内存不足——composer update 阶段建议 memory_limit ≥ 1.5G;另外,私有包每次 git checkout 都计入 process-timeout 总耗时,不是单独计时。











