根本原因是composer默认超时阈值低、并行下载放大压力、未配github token导致api限流、未换国内镜像源;须同步执行四步:配token、调高process-timeout至600、禁用并行、换阿里云镜像源。

Composer拉取 GitHub 依赖超时,本质不是网络断了,而是默认配置在对抗低响应场景时完全失效——必须同时调高超时、禁用并发、配好认证、换掉源,缺一不可。
为什么composer install卡在Downloading或报Connection timed out
GitHub API 和 Git clone 都受限于 Composer 默认的 process-timeout(60 秒)和默认开启的并行下载。国内直连 github.com 常有 2–5 秒首字节延迟,加上 Composer 每个包单独发起 HTTPS 请求 + 解析 tag 列表,极易触发 curl: (28) Operation timed out 或静默中断。
-
process-timeout是全局硬限制,超时后直接 kill 进程,不重试 - 并行下载(
parallel)会放大连接压力,尤其在 CI 容器里 DNS 解析慢或 socket 资源紧张时 - 未配 GitHub Token 时,API 请求走未认证流,每小时仅 60 次限额,
--prefer-source或私有 repo 场景下几秒就耗尽 - 镜像源(如阿里云)只加速
packagist.org元数据和.zip包,对git clone https://github.com/...无效
必须执行的四步修复操作
以下顺序不能颠倒,漏掉任意一步都可能让前序配置白费:
- 先配 GitHub Token:
composer config --global github-oauth.github.com <your-token></your-token>,然后立刻执行chmod 600 ~/.composer/auth.json(权限不是 600,Composer 会静默忽略) - 提高超时阈值:
composer config -g process-timeout 600(单位秒),CI 中建议改环境变量:COMPOSER_PROCESS_TIMEOUT=600 - 禁用并行下载:
composer config -g use-include-path false,再加COMPOSER_DISABLE_PARALLEL=true确保生效 - 换国内镜像源(仅加速公共包):
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
composer.json里写 GitHub 私有仓库要注意什么
即使配了 Token,如果 composer.json 里的仓库定义不规范,依然会认证失败或 fallback 到匿名请求:
- URL 必须是 HTTPS 格式:
"url": "https://github.com/username/private-repo.git",不能是git@或ssh://(除非你已配好 SSH 密钥且确认git命令能通) - 必须显式声明
"type": "vcs",否则 Composer 不识别为版本库,会跳过认证逻辑 - 避免在
repositories里混用packagist镜像和 GitHub URL——镜像不代理 VCS,反而可能干扰解析顺序 - 私有包 require 版本尽量用
dev-main或带 commit hash 的dev-xxxxxxx,少用模糊的^1.0,减少 API 查询次数
CI 环境中容易被忽略的关键点
GitHub Actions / GitLab CI 里问题更隐蔽,因为错误常被吞掉或归因为“网络超时”:
-
actions/checkout@v4后必须加working-directory: ${{ github.workspace }},否则composer install在空目录运行,连composer.json都读不到 - 缓存路径要设对:
~/.composer/cache可缓存元数据和 zip 包,vendor/不该缓存(不同 PHP 版本或扩展会导致 autoload 失败) - 务必加
--no-interaction --prefer-dist --optimize-autoloader,CI 下缺任何一项都可能卡住或生成低效 autoloader - PHP 扩展缺失(如
openssl、zlib、mbstring)会导致解压失败或 HTTPS 握手异常,但错误日志常只显示“Connection refused”
最麻烦的其实是组合问题:Token 权限不对 + process-timeout 过短 + 并行开启 + 私有仓库 URL 写成 SSH 格式,这四者叠在一起,调试时会互相掩盖真实原因。建议每次只改一项,用 composer install -vvv 观察哪一步卡住,再针对性处理。











