项目级镜像需在项目根目录composer.json的repositories数组首位配置type为composer的镜像源,并显式禁用packagist.org,改配置后须删除vendor和composer.lock再执行composer install。

composer.json 里怎么写镜像配置才生效
项目级镜像不是全局设置,必须写在项目根目录的 composer.json 里,且只对当前项目起作用。写错位置(比如写进 composer.lock 或全局 config.json)就完全不生效。
关键点是用 repositories 覆盖 Packagist 官方源,而不是改 config.mirror——后者只在旧版 Composer 1.x 里支持,Composer 2.x+ 已废弃。
- 必须把镜像源作为 type
composer的仓库,放在repositories数组首位 -
packagist.org必须显式禁用:{"packagist.org": false} - 国内常用镜像地址如阿里云:
https://mirrors.aliyun.com/composer/,清华:https://packagist.phpcomposer.com(已停用),推荐用https://mirrors.tuna.tsinghua.edu.cn/composer/
{
"repositories": [
{
"type": "composer",
"url": "https://mirrors.tuna.tsinghua.edu.cn/composer/"
},
{"packagist.org": false}
]
}
运行 install/update 前要不要删 vendor 和 lock
要删。Composer 不会自动“刷新”镜像源逻辑——它读 composer.lock 时直接按里面记录的 dist URL 下载,根本不会查 repositories 配置。所以改完 composer.json 后,composer install 可能还在用旧 URL,甚至报 404。
- 必须先删掉
vendor/和composer.lock - 再执行
composer install(不是update),让 Composer 重新解析依赖并生成新 lock 文件 - 如果只跑
composer update,它可能沿用旧 lock 里的 URL,镜像配置形同虚设
为什么换了镜像还是连不上 packagist.org
常见原因是没关掉 Packagist 自动 fallback。Composer 默认即使你配了自定义仓库,遇到包不存在时仍会去 packagist.org 查一次——这会导致超时或被墙,尤其在 CI 环境里特别明显。
- 必须加
{"packagist.org": false}这行,不能只写镜像 URL - 注意格式:它是
repositories数组里的一个独立对象,不是字段值 - 有些镜像(如腾讯云)同步延迟较高,如果包刚发布不久,镜像里还没同步到,就会因
packagist.org被禁用而报Could not find package xxx
CI/CD 里镜像配置失效的典型原因
GitLab CI、GitHub Actions 等环境常缓存 composer.lock 或 vendor,导致本地改了配置,流水线里还在用旧 lock 文件,镜像根本没走。
- 确保 CI 脚本中明确执行
rm -rf vendor composer.lock再composer install - 不要依赖
composer install --no-interaction就以为能跳过问题——它不解决 lock 文件残留 - 某些私有 Git 仓库若用了子模块或 submodule,主项目
composer.json的镜像配置不会透传到子模块,得各自单独配
最麻烦的是 lock 文件里混着不同源的包——比如部分包来自镜像,部分来自 packagist.org(因为之前没关掉 fallback),这种混合状态很难排查,只能重生成 lock。











