必须显式声明"type": "vcs"和以.git结尾的合法url,否则composer完全忽略该仓库;require中包名须与私有仓库composer.json的"name"字段严格一致;需配置"packagist.org": false并正确设置auth.json认证。

repositories数组里必须显式声明type和url
Composer不会自动识别私有Git仓库,哪怕URL是合法的HTTPS或SSH地址。漏掉"type": "vcs"会导致整个条目被忽略,composer install时完全不尝试连接该仓库。
常见错误写法:"url": "https://gitlab.com/acme/utils"(缺.git后缀、缺type);正确写法必须包含:
-
"type": "vcs"(小写,不能写成VCS或git) -
"url"以.git结尾(如"https://gitlab.com/acme/utils.git") - 若用SSH,格式为
"git@gitlab.com:acme/utils.git",且本地需配置好SSH agent
require里的包名必须和私有仓库composer.json中name字段完全一致
Composer匹配依赖时,只认私有仓库根目录下composer.json里的"name"值,不是仓库名、不是路径名、也不是GitHub组织名。
例如私有仓库composer.json含"name": "acme/utils",则主项目require只能写:"acme/utils": "dev-main"。写成"utils"、"acme-utils"或"acme/utils-dev"都会报Could not find package。
分支别名必须存在:如果私有仓库没打tag,就只能用dev-xxx形式,且xxx必须是真实存在的分支名(大小写敏感)。
不关packagist.org,私有包永远不生效
默认情况下,Composer会先查packagist.org,查不到才 fallback 到repositories列表——但私有包根本不在Packagist上,所以这个 fallback 永远不会触发。
必须在项目级composer.json根层级加这一行:"packagist.org": false。它不是repositories里的子项,而是同级配置。
容易踩的坑:
- 写成
"packagist": false(少.org)→ 无效 - 写在
repositories数组内部 → 被忽略 - 用了Artifactory/Satis等镜像源却没关默认源 → 私有包始终404
认证信息绝不能写进composer.json
Bitbucket/GitHub/GitLab的token、密码、App Password都禁止硬编码在composer.json里。一旦提交到Git,等于泄露凭证。
正确做法分两步:
- Bitbucket:在项目根目录建
auth.json,内容为{"bitbucket.org": {"http-basic": {"bitbucket.org": {"username": "xxx", "password": "app-password"}}}} - GitHub/GitLab:用
composer config -g写入全局配置,如composer config -g github-oauth.github.com abc123... - 所有
auth.json文件必须加进.gitignore
验证是否生效:运行composer diagnose,看输出里是否有HTTP basic authentication is configured for bitbucket.org之类提示。
最常被忽略的一点:私有仓库自己的composer.json里,"name"和"version"(或"minimum-stability")必须合理,否则即使URL和认证都对,Composer也会因元数据缺失而跳过解析。











