ci中git clone卡住的根本原因是基础镜像未安装git,而非网络慢;需在dockerfile中为debian/ubuntu加apt install git、alpine加apk add git,并验证git --version,同时强制--prefer-dist、禁用prefer-source、设置process-timeout及清理vendor确保环境干净。

CI中git clone卡住,不是网络慢而是没装git
很多CI构建失败报错类似 Failed to clone https://github.com/xxx 或 sh: git: not found,根本原因不是超时,是基础镜像压根没装 git。Docker 默认镜像(如 php:8.3-cli)不含 git,而 Composer 在 --prefer-source、dev 分支或私有 VCS 包场景下必须调用系统 git 命令。
实操建议:
- Debian/Ubuntu 镜像加
RUN apt-get update && apt-get install -y git - Alpine 镜像加
RUN apk add --no-cache git - 验证是否生效:在 CI 脚本里加一行
git --version,确保输出版本号而非 command not found - 别信“CI 平台自带 git”——GitHub Actions 的
ubuntu-latest有,但自建 Runner 或私有 Kubernetes Job 很可能没有
镜像源对 git 操作完全无效,必须强制用 dist
国内镜像(如阿里云 https://mirrors.aliyun.com/composer/)只代理 dist 包(ZIP/TAR),不代理任何 Git 克隆行为。一旦项目依赖含 "type": "vcs" 的包、用了 dev-main 分支,或全局配置了 prefer-source: true,镜像就彻底失效,CI 仍会直连 GitHub/GitLab,触发超时。
实操建议:
- CI 脚本开头加
composer config -g prefer-source false,关掉源码模式 - 安装命令统一加
--prefer-dist:如composer install --prefer-dist --no-interaction - 检查项目
composer.json是否硬编码了repositories,尤其是把私有 GitLab 地址写成https://gitlab.example.com而非https://gitlab.example.com/api/v4——这类地址会被 Composer 当作 VCS 源,绕过镜像
process-timeout 和 COMPOSER_PROCESS_TIMEOUT 必须双设
CI 中 composer install 卡在 Executing command(比如 git clone 或 unzip)时,http.timeout 不起作用,真正管用的是控制子进程生命周期的 process-timeout。但部分 Composer 插件和自定义 installer 会忽略命令行参数,只读环境变量。
实操建议:
- 全局设
composer config -g process-timeout 1200(20 分钟) - 同时导出环境变量:
export COMPOSER_PROCESS_TIMEOUT=1200 - 不要设
http-basic.timeout——Composer v2+ 完全不读这个字段 - 避免只改
--timeout=1200,它只约束命令总时长,对正在运行的git子进程无感
vendor 目录残留导致 git 操作反复失败
CI 构建常复用旧 vendor 目录(尤其用缓存时),若其中某个包是上次用 --prefer-source 拉下来的,它的 .git 目录可能损坏、分支指向异常,或远程 URL 已变更。Composer 会尝试复用该目录并执行 git fetch,结果卡死或报 Could not fetch。
实操建议:
- CI 脚本开头加
rm -rf vendor,从干净状态开始 - 或更轻量:用
composer clear-cache+composer install --no-cache - 如果必须复用 vendor 缓存,确保缓存策略与
--prefer-dist严格绑定,禁止混用 source/dist
最易被忽略的一点:CI 中所有 Composer 配置(镜像、timeout、prefer-dist)都必须在构建脚本开头显式执行,不能依赖本地机器已配好的 COMPOSER_HOME——容器每次启动都是全新环境,配置不固化就等于没配。











