gitlab ci中composer config -g不生效的典型表现是composer install仍走packagist.org,根本原因是配置被写入root用户路径而runner用户读不到;必须由runner用户在ci容器内执行严格校验的命令(键名repo.packagist、type值composer、url末尾带/),并配合缓存~/.composer/cache和vendor/才能真正提速。

GitLab CI里composer config -g不生效的典型表现
执行composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/后,composer install依然走packagist.org、日志出现Downloading https://repo.packagist.org/packages.json——说明配置根本没被读到。
根本原因是:CI job 默认以runner用户运行,但你本地用sudo或root执行的composer config -g写进了/root/.composer/config.json,而runner用户家目录是/home/gitlab-runner,完全不读那个文件。
- 查当前用户:
whoami或看 CI 日志开头的Running with gitlab-runner ... on ...后面的用户名 - 确认配置路径:
echo $HOME+ls -la $HOME/.composer/config.json - 别在本地配完就提交脚本——配置必须在 CI 容器内由
runner用户当场执行
正确写法:在.gitlab-ci.yml中直接注入镜像配置
把镜像设置变成 CI 脚本的一部分,而不是靠人工预置。关键点是:命令必须由 job 当前用户执行,且参数严格校验。
示例片段(放在before_script或具体 job 的script开头):
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ composer config -g --unset github-protocols
-
-g不能省,否则只改当前目录下的composer.json,对后续install无影响 - URL末尾
/必须存在,少它会拼出https://mirrors.aliyun.com/composer/packages.json→ 404 → fallback 到官方源 -
github-protocols默认设为["https", "ssh"],CI 环境通常没 SSH key,关掉可避免卡在 Git clone - 执行后立刻验证:
composer config -g repo.packagist输出应为完整 JSON,不是null或空行
为什么不能只靠项目级repositories配置?
项目根目录composer.json里写"repositories": [{"type":"composer","url":"https://mirrors.aliyun.com/composer/"}]看似简单,但在 CI 中容易失效。
问题在于:这个配置只影响当前项目声明的依赖,一旦某个依赖包(比如monolog/monolog)自己在composer.json里写了"repositories"字段,Composer 就会优先用它的源,你的镜像配置就被绕过了。
- 全局
repo.packagist是 Composer 唯一能强制接管packagist.org元数据请求的机制 - 私有包必须单独列在
repositories数组里,且排在 packagist 镜像之前,顺序决定优先级 - 如果项目已禁用 packagist(
"packagist.org": false),全局镜像会被彻底忽略——这种写法在 CI 中要主动删掉
缓存和镜像必须同时生效才真正提速
只配镜像不设缓存,或只缓存vendor/不缓存~/.composer/cache,都达不到预期效果。GitLab CI 中二者缺一不可。
.gitlab-ci.yml中必须显式声明两处缓存路径:
cache:
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
- vendor/
- $HOME/.composer/cache/
-
vendor/缓存让后续 job 直接复用已安装的包,跳过下载解压 -
$HOME/.composer/cache/缓存 ZIP 包本身,避免重复下载同一版本 - 注意:
$HOME在 GitLab 官方 Runner 中指向/home/gitlab-runner,路径必须带/结尾,否则缓存不命中 - 如果用了
--classmap-authoritative,vendor/缓存还必须保证 PHP 版本、扩展、OS 文件系统一致,否则autoload_static.php可能失效
GitLab CI 里镜像配置最易被忽略的细节,不是 URL 写错,而是没确认执行用户和配置落盘路径是否匹配——一个whoami加一行ls -la $HOME/.composer/config.json,比反复重试快得多。











