卡在Downloading https://时只看http.timeout,因Composer 2.x中该参数控制DNS解析、TLS握手、首字节等待及整个body传输的总时间,默认300秒,而process-timeout、config.timeout和--timeout均不参与HTTP下载阶段。

直接调 http.timeout,不是 timeout、config.timeout 或 --timeout —— 后三者全无效。
为什么卡在 Downloading https:// 时只看 http.timeout
Composer 2.x 中,所有 HTTPS 包下载(包括拉 packages.json、ZIP 包头、完整 body)都走同一套 HTTP 生命周期:DNS 解析 → TLS 握手 → 首字节等待 → 整个响应体传输。这个总耗时由 http.timeout 控制,单位是秒,默认仅 300(5 分钟)。弱网或拉大包(如 Laravel dist)时极易触发 cURL error 28 或反复 retry 失败。
-
process-timeout完全不参与——它只管git clone、unzip、tar这类子进程 -
config.timeout是废弃字段,Composer 根本不识别,写了也白写 -
--timeout=600是process-timeout的别名,和 HTTPS 下载无关
怎么设才真正生效
必须同步处理两层:Composer 配置 + PHP 底层 socket 设置。否则改了 http.timeout 也白搭。
- 项目级(推荐,可提交):
composer config http.timeout 1200,写入当前composer.json的config段 - 全局级:
composer config -g http.timeout 1200,写入~/.composer/config.json - 临时覆盖(CI 最常用):
COMPOSER_HTTP_TIMEOUT=1200 composer install - 但必须同步检查 PHP CLI 的
default_socket_timeout:php -i | grep default_socket_timeout,若值是默认的60,cURL 会在 60 秒就底层掐断——哪怕你设了1200 - 临时验证:
php -d default_socket_timeout=1200 composer install
Composer 2.2+ 可额外加一层细粒度控制
旧版本只能靠 http.timeout 硬扛;2.2+ 新增 http-basic-timeout,专管单次 GET 的连接 + 读取(比如拉 packages.json 或 ZIP 包前几 KB),不涉及整个 body 下载。适合防握手慢导致的中断。
- 设为
300已足够:composer config -g http-basic-timeout 300 - 注意:
http-basic-timeout和http.timeout是并行关系,不是子集;两者都要设才稳妥 - 它不能替代
http.timeout,因为 ZIP 包主体传输仍由后者兜底
真正容易被忽略的是:HTTPS 请求超时只是第一关,后面 unzip、git clone、甚至自定义脚本执行,各自有独立的超时机制,且互不感知。光调 http.timeout,大概率在下一步就卡住。











