卡在git clone或unzip时应调process-timeout,它控制子进程执行时限,默认300秒,超时即被强制终止;卡在Downloading https://时应调http.timeout,控制HTTP全周期(DNS、TLS、首字节、body传输)总时间,默认300秒,且须同步调高PHP的default_socket_timeout。

Composer 没有“调度超时”这个概念,所谓“调度超时”是误用术语——你真正想调的,是 process-timeout(子进程执行时限)或 http.timeout(HTTP 下载总时限),二者完全不重叠,也不能互相替代。
卡在 git clone 或 unzip 时该调哪个?
这是典型的 process-timeout 生效场景。Composer 把 git clone、unzip、post-install-cmd 脚本等全部扔进独立子进程执行,而 process-timeout 就是控制每个子进程最多能活多久。
- 默认值仅
300秒(5 分钟),大包或低配 CI 环境极易触发[RuntimeException] The process "git clone ..." exceeded the timeout - 它和网络无关,哪怕代理通畅、镜像飞快,只要
git clone本身耗时超限,就会被强制 kill - 必须设为整数秒,设
0表示禁用超时(慎用,可能无限挂起) - 项目级最稳:
composer config process-timeout 1200,写入当前composer.json的config段 - CI 中推荐环境变量兜底:
COMPOSER_PROCESS_TIMEOUT=1800
卡在 Downloading https://... 时该调哪个?
这是 HTTP 下载阶段,比如拉 packages.json 或 ZIP 包,错误里常带 cURL error 28 或反复 retry 后失败。此时 process-timeout 完全不生效,只认 http.timeout。
-
http.timeout控制 DNS 解析 + TLS 握手 + 首字节等待 + 整个 body 传输的总时间,单位秒,默认300 - 但光改它没用:PHP CLI 的
default_socket_timeout若低于该值(常见是60),底层 socket 会提前掐断,cURL 直接报错 - 查当前值:
php -i | grep default_socket_timeout - 临时改(CI 推荐):
php -d default_socket_timeout=1200 composer install - 项目级固化:
composer config http.timeout 600
为什么 --timeout=600 有时不起作用?
这个命令行参数只覆盖 process-timeout,且仅对当前命令生效。但它无法干预 HTTP 下载阶段——如果你卡在下载 ZIP,哪怕加了 --timeout=600,照样会因 http.timeout 或 default_socket_timeout 触发失败。
- 必须带等号:
--timeout=600,写成--timeout 600会被静默忽略 - Composer 2.2+ 才支持
--http-basic-timeout单独调 HTTP 层,旧版本只能靠配置项 - 它不解决资源瓶颈:磁盘 I/O 慢、内存不足、vendor 目录挂载在 NTFS/WSL2 上,都可能导致子进程假死,超时只是表象
真正容易被忽略的是:超时设置只是“容错开关”,不是性能解药。国内用户不切镜像源、不配代理、不清理冗余 repositories 字段,光调 timeout 基本白忙——因为大部分“超时”本质是请求发到了慢如蜗牛的源上,而不是时间不够。


















