私有包被国内镜像“劫持”是因为镜像复刻了packagist.org全部元数据,若同名包存在,Composer会优先从镜像拉取而非私有源;必须在composer.json根层级设"packagist": false禁用默认源,并将私有源显式声明且置于repositories数组前列,否则仍会fallback到镜像导致覆盖。

为什么私有包会被国内镜像“劫持”
国内镜像源(如阿里云、清华)是 packagist.org 的完整复刻,只要你的私有包名恰好和公开包重名(比如 acme/logger),哪怕你只在 repositories 里声明了公司 GitLab 源,Composer 仍可能从镜像里拉取一个同名但版本错误甚至不存在的包——因为默认行为是:先查镜像,再 fallback 到你声明的私有源(如果没关默认源的话)。
必须关掉 packagist.org 的自动映射
关键不是删镜像,而是让 Composer 彻底不查 packagist.org。这个开关只认一个写法:
-
"packagist": false必须写在composer.json根层级,不能嵌套,不能加引号变体(比如"packagist.org": false无效) - 设完后,所有包都必须显式出现在
repositories数组里,否则报Package not found - 别指望
"repositories": [{"packagist.org": false}]这种写法——它只是个普通仓库条目,不触发全局禁用逻辑
私有包要单独声明,且顺序靠前
镜像源和私有源混在一个 repositories 数组里,但 Composer 查找时按顺序匹配。一旦前面的源(比如镜像)返回了同名包元数据,后面私有源就根本不会被访问。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 把私有 Git 包写成
type: "package"+dist指向 tarball,避免每次 clone - 若用内部 Composer 仓库(如 Satis),用
type: "composer",URL 写内网地址 - 确保私有源条目排在镜像源前面,例如:
"repositories": [ {"type": "package", "package": {...}}, {"type": "composer", "url": "https://gitlab.internal/api/v4/groups/acme/-/composer"} ]
项目级配置比全局更可靠
全局镜像(composer config -g repo.packagist)在 CI 或宝塔环境里常因用户权限失效;而项目级 repositories 直接写进 composer.json,谁执行命令都生效。
- 执行
composer config repo.packagist composer https://mirrors.aliyun.com/composer/(不带-g)会覆盖整个repositories对象,记得手动补回私有源 - 如果已有
repositories块,别直接composer config覆盖——改composer.json手动加"packagist": false和私有源更稳妥 - 换完立刻
composer clear-cache,否则旧缓存里的镜像元数据还会干扰解析
真正起作用的从来不是“换镜像”,而是“切断默认源 + 显式声明路径”。漏掉 "packagist": false 或者私有源顺序不对,再多镜像配置也白搭。

















