必须同时调高http.timeout(控制DNS、TLS、首字节及body传输,建议600秒)和process-timeout(控制git clone、unzip等子进程,建议1200秒),并同步提升PHP的default_socket_timeout,且务必配置国内镜像源。

Composer 默认 300 秒超时确实太短,尤其在国内弱网、大包或私有 Git 仓库场景下几乎必挂;必须同时调高 http.timeout 和 process-timeout,缺一不可。
卡在 Downloading https:// 时该改 http.timeout
这是 HTTP 请求全周期超时,包括 DNS 解析、TLS 握手、首字节等待、整个 ZIP body 传输——错误里常见 cURL error 28 或反复 retry 后失败。它和 process-timeout 完全无关。
-
http.timeout默认仅 300 秒(Composer 2.x),建议设为600(10 分钟)起步,CI 环境可临时用COMPOSER_HTTP_TIMEOUT=1200 - 项目级配置最稳:运行
composer config http.timeout 600,会写入当前composer.json的config段,可提交、可复现 - 必须同步检查并调高 PHP CLI 的
default_socket_timeout:运行php -i | grep default_socket_timeout,若值是默认的60,哪怕你设了http.timeout=1200也会在 60 秒被底层 socket 强制掐断
报 “The process timed out” 该改 process-timeout
错误信息明确含 [RuntimeException] The process "" exceeded the timeout,说明是子进程(如 git clone、unzip、php artisan)执行太久被杀,和网络下载无关。
-
process-timeout控制单个外部命令最大执行时间,默认 300 秒,建议设为1200(20 分钟)起步 - 全局生效:运行
composer config -g process-timeout 1200,写入~/.composer/config.json - 项目级生效:直接在
composer.json顶层加"config": {"process-timeout": 1200} - 不推荐设为
0或-1:CI 中一旦遇到私有 Git 仓库不可达或网络卡死,会无限挂起无响应
为什么 set_time_limit(0) 和 max_execution_time 完全无效
Composer 是命令行 PHP 应用,但它自己封装了 HTTP 下载逻辑(基于 cURL)和子进程管理(proc_open),完全不走 PHP 的脚本执行超时机制。
- 改
php.ini里的max_execution_time或在代码里调set_time_limit(0)对 Composer 命令本身毫无影响 - 同理,
composer self-update走独立逻辑,不受http.timeout或process-timeout控制 - 真正起作用的只有 Composer 自己定义的两个配置项:
http.timeout和process-timeout
国内用户不配镜像源,调再大 timeout 也没用
即使把 http.timeout 设到 3600,如果还直连 packagist.org 或 GitHub,DNS 解析慢、TLS 握手卡顿、中间路由抖动仍会导致频繁 cURL error 28。
- 务必配国内镜像源,例如阿里云:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ - 私有 Git 包建议用
github-oauth配 token,避免 GitHub API 限速触发超时:composer config -g github-oauth.github.com "xxx" - 镜像源 + 合理 timeout + 同步调高
default_socket_timeout,才是完整闭环
最容易被忽略的是 PHP CLI 的 default_socket_timeout 和镜像源的组合使用——只调 Composer 配置,不碰 PHP 底层 socket 设置,等于白调;只换镜像不调 timeout,大包仍可能失败。











