Composer 镜像优先级由 repositories 数组顺序和 "packagist": false 共同决定:私有源需置首并设为 "vcs" 类型,阿里云镜像放其后作兜底,且必须将 {"packagist": false} 置数组末尾以禁用官方源。

Composer 里没有“镜像优先级”这个独立配置项,所谓优先级,完全由 repositories 数组的顺序 + "packagist": false 开关共同决定。不关掉默认源,私有包或自定义镜像根本不会被优先选用。
repositories 数组顺序决定实际查找顺序
Composer 严格从 repositories 数组第一个元素开始遍历,遇到第一个能返回目标包元数据(即包含该 vendor/package 且有可用版本)的仓库,就立刻停止查找,后续仓库完全不触发。
- 想让私有 Git 仓库优先:把它放在数组最前面,类型必须是
"type": "vcs",URL 用裸 HTTPS 地址(如https://git.example.com/my/monolog),不要加.git后缀 - 想让阿里云镜像作为公开包兜底:把它放在私有源之后,类型为
"type": "composer" - 如果两个仓库都提供
monolog/monolog,但私有源在第二位,而第一位的镜像返回了 200 + 元数据,Composer 就不会查你的私有源
必须显式禁用 packagist.org 才能让顺序真正生效
默认情况下,Packagist 官方源是隐式兜底源——哪怕你写了 repositories,它也总在最后被查。只有加上 {"packagist": false} 这一项,才能关闭它,让数组顺序成为唯一决策依据。
-
{"packagist": false}必须写在repositories数组里,且要放在所有真实仓库声明之后(它不是仓库,是开关) - 错误写法:
"repositories": [{"packagist": false}, {"type": "vcs", ...}]—— 这会导致后续仓库被跳过 - 正确结构示例:
"repositories": [ { "type": "vcs", "url": "https://git.example.com/my/monolog" }, { "type": "composer", "url": "https://mirrors.aliyun.com/composer/" }, { "packagist": false } ]
国内镜像不支持 dev 分支和私有包,别指望它们兜底
阿里云、腾讯云等镜像只同步 packagist.org 上已收录的 stable tag 和 release 版本,dev-main、dev-feature/x 这类分支根本不会被抓取。同时,它们也不托管任何私有包——你把私有源 URL 塞进镜像配置里,毫无意义。
- 需要拉
dev分支?只能靠"type": "vcs"直连 Git 仓库,不能依赖镜像 - 镜像只代理元数据(
packages.json),dist 包下载链接仍指向原始 GitHub/GitLab,镜像不加速 tarball 下载 - 用
composer config -g repo.packagist设置全局镜像,会覆盖项目级repositories,导致私有源失效;项目内务必显式声明全部所需源
验证是否生效的实操方法
别只看配置文件,直接看 Composer 实际行为:
- 运行
composer config repositories,确认输出中包含你的私有源 URL,且"packagist": false已出现 - 加
-vvv执行composer require my-company/utils,日志里会明确打出请求了哪个源的packages.json - 用
curl -I https://your-private-repo.com/packages.json确保返回 200,否则 Composer 查到 404 就直接报错,不会往下试 - 如果私有源用的是
"type": "package",必须手动写全version、dist字段,否则composer install会静默跳过
最容易被忽略的一点:项目级 composer.json 中的 repositories 会完全覆盖全局配置,而不是合并。这意味着你不能只在全局设个阿里云镜像就完事——每个要用私有包的项目,都得自己完整写一遍带顺序和开关的仓库列表。


















