ci/cd中composer慢的根本原因是未切国内镜像、缓存路径错误、关键参数缺失;必须配置阿里云镜像、缓存~/.composer/cache(非vendor/)、并严格使用--no-dev --prefer-dist --optimize-autoloader --classmap-authoritative --no-interaction参数。

CI/CD里Composer慢,不是“中文”问题,也不是网络抽风——根本原因是没切国内镜像、缓存路径错、参数漏设。三者缺一,提速就白忙。
composer config -g repo.packagist 输出还是 packagist.org?
这说明镜像根本没生效,后续所有优化都打水漂。常见原因有三个:
- CI脚本用
sudo composer config -g,结果写进了root的~/.composer/config.json,但构建实际跑在runner或www用户下,压根读不到 - 拼错字段名,比如写成
repos.packagist(多一个s),Composer静默忽略,composer config -g repo.packagist查出来仍是空 - 旧版 Composer 1.x 不支持
repo.packagist,得改用composer config -g repos.packagist '{"type":"composer","url":"https://mirrors.aliyun.com/composer/"}'
验证是否真走镜像:加 -vvv 运行 composer install,日志里出现 GET https://mirrors.aliyun.com/composer/p2/ 才算成功。
缓存 vendor/ 还是 ~/.composer/cache?
必须缓存 ~/.composer/cache,绝不能缓存 vendor/。原因很实在:
-
vendor/里的 autoloader 是编译时生成的,依赖 PHP 版本、扩展(如ext-zip)、OS 架构;缓存错环境,上线后直接报Class not found -
~/.composer/cache只存下载的 zip 包和元数据,跟composer.lock哈希强绑定,与运行环境完全无关 - GitHub Actions 示例:
path: ~/.composer/cache,key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} - GitLab CI 示例:
cache: key: ${PHP_VERSION}-composer-cache; paths: - ~/.composer/cache
composer install 必须带哪些参数?
不是“能跑就行”,而是要同时满足可重现、安全、性能。漏一个,就可能出问题:
-
--no-dev:跳过require-dev中的包(如phpunit),否则上线后class_exists('PHPUnit\Framework\TestCase')直接 fatal -
--prefer-dist:强制下载预构建 zip 包,避免 Git clone 失败、SSH 权限缺失或协议阻塞 -
--optimize-autoloader(或-o):生成vendor/composer/autoload_classmap.php,绕过 PSR-4 运行时扫描,类加载快 50%+ -
--classmap-authoritative:告诉 autoloader “没在 classmap 里 = 真没有”,彻底禁用file_exists()探测——这是防止Class not found的最后一道防线 -
--no-interaction和--no-progress:禁用交互提示和进度条,避免流水线卡住或日志解析失败
注意:--classmap-authoritative 必须与 --no-dev 同时使用;否则 dev 类虽不装,运行时判断仍会触发 fatal。
CI 里为什么不能用 composer update?
因为 composer update 会重解析整个依赖树、修改 composer.lock,破坏构建可重现性。昨天通过的流水线,今天可能因一个 monolog 的 patch 升级而失败。
- CI 中只允许
composer install,且必须确保composer.lock已提交到 Git - 本地改了
composer.json后,手动运行composer update并提交新composer.lock,再推送到 CI - CI 脚本里一旦出现
composer update,应立刻删除 - 如果 CI 报
Lock file operations: 1 install, 0 updates, 0 removals却卡住,大概率是 PHP 扩展缺失(比如 Alpine 镜像没装apk add php81-zip),不是命令问题
最易被忽略的一点:换镜像源后,务必执行 composer clear-cache,否则旧源还在内存里苟着,-vvv 日志里看到的仍是 packagist.org 的请求。











