解决Composer执行过程超时:全局延长执行时间【必看】

Composer install/update 卡在 downloading 或 hanging 怎么办
相信不少开发者都遇到过这个场景:执行 composer install 或 composer update 时,进度条在 Downloading... 那里一卡就是半天,最后要么直接报错,要么干脆没了下文。这其实不是你的本地环境出了问题,而是Composer默认的300秒(5分钟)网络请求超时被触发了——尤其是在使用某些较慢的镜像源,或者下载体积较大的依赖包时,这种情况几乎成了家常便饭。
遇到这种情况,一个立竿见影的临时解决方案是,在命令后面加上 --timeout=0 参数,比如:composer update --timeout=0。这里的“0”代表不限制超时时间,让Composer可以一直等下去。不过,每次都手动输入这个参数实在太麻烦,更别提在CI/CD自动化脚本里,一旦忘记加上,构建流程就可能因此失败。所以,更一劳永逸的办法,是设置全局配置。
需要特别注意的是,这个 --timeout 参数主要影响的是下载阶段的HTTP请求超时,它并不控制后续的脚本执行或自动加载器(autoloader)生成等耗时操作。
如何永久设置全局超时时间
想要永久生效,就得借助 composer config 命令,将配置写入全局范围。这样一来,当前用户下的所有项目都会生效(除非单个项目有自己的配置覆盖了它)。
composer config -g process-timeout 0
敲下这行命令,问题就解决了一大半。这里有个关键点必须厘清:process-timeout 控制的是“每个外部子进程”的最大运行时间,比如 git clone、unzip 解压、执行PHP脚本等,默认也是300秒。而之前提到的 timeout(没有 process- 前缀)控制的仅仅是HTTP请求的超时。两者作用范围不同,千万别搞混了。
将 process-timeout 设为 0,意味着彻底禁用超时限制,这是最彻底的做法,尤其适合内网环境、持续集成(CI)流程或者你完全信任的源。如果觉得完全不限时有点不安,也可以设一个更大的值,比如3600秒(1小时):composer config -g process-timeout 3600。
想查看当前设置的值?用 composer config -g process-timeout 就行。这个配置最终会写入 ~/.composer/config.json 文件,虽然你可以手动编辑这个文件,但还是更推荐使用命令来操作,以免不小心写错了格式。
HTTP 超时(timeout)和 process-timeout 的区别
很多人之所以调整了配置却不见效,根本原因就是混淆了这两个参数。咱们再来明确一下:
timeout:只管Composer自身发起的HTTP请求,例如访问Packagist.org或私有仓库的API接口,单位是秒,默认300。process-timeout:管辖所有被Composer调用的子进程,包括git、svn、unzip、php等等,单位也是秒,默认300。
实际上,大多数“卡住”的情况,罪魁祸首并不是HTTP下载,而是 git clone 仓库速度慢,或者解压一个巨大的ZIP包耗时过长。因此,调整 process-timeout 才是解决问题的关键所在。
当然,HTTP超时也可以通过 composer config -g timeout 600 单独调整,但在绝大多数场景下,优先调整 process-timeout 就已经足够了。
CI/CD 或 Docker 环境下要注意什么
在GitHub Actions、GitLab CI或Docker构建这类环境中,情况会稍微复杂一些。通过 composer config -g 写入的配置,是保存在构建容器的临时用户家目录下的。每次启动一个新的构建容器,这个配置都会丢失,无法持久化。
所以,在这些自动化环境里,不能指望一次性的全局设置。推荐的做法是,在CI脚本的开头就显式地执行设置命令:composer config --global process-timeout 0。如果是在Dockerfile中构建,则可以添加一行:RUN composer config --global process-timeout 0。
另外,一些官方或社区维护的Docker镜像(例如 composer:2)可能已经默认将超时设为了0,但如果你使用的是自己构建的基础镜像,最好还是检查确认一下。
还有一个优先级更高的设置方式:环境变量。如果设置了 COMPOSER_PROCESS_TIMEOUT 这个环境变量,它的值会直接覆盖配置文件里的 process-timeout 设置。
最后,我们来理清一下所有配置的生效顺序,避免互相“打架”:命令行参数 > 环境变量 > 项目级配置(composer.json) > 全局配置(~/.composer/config.json)。这意味着,如果你既改了全局配置,又设置了环境变量,那么最终会以环境变量的值为准。
话说回来,将 process-timeout 设为0虽然是救急的关键一招,但也并非毫无风险。如果真的遇到了死循环或者彻底挂起的git进程,Composer就会一直等待下去。这时候,就需要依靠手动终止进程,或者在外层包装脚本设置超时来兜底了——这一点,常常被人忽略。