私有仓库必须声明为vcs类型,不能用package手动定义;需在composer.json中配置vcs源、正确设置auth.json路径与权限、私有包需规范命名并打语义化tag,且应避免使用全局repositories配置。

私有仓库必须声明为 vcs 类型,不能用 package 手动定义
Composer 默认只信任 Packagist 上的公开包,拉取私有 Git 仓库时,必须让 Composer 明确知道这是一个版本控制系统源(vcs),否则会报 Could not find a matching version of package xxx 或直接跳过解析。手动在 repositories 里用 package 类型硬编码版本,不仅维护成本高,还会导致 composer update 无法自动识别新 tag。
- 正确做法:在
composer.json的repositories数组中添加类型为vcs的条目,URL 指向仓库地址(如git@github.com:org/private-lib.git或https://gitlab.example.com/group/lib.git) - SSH 地址需确保当前用户能免密访问(
ssh -T git@github.com可通);HTTPS 地址若需认证,应配置auth.json(见下节) - 不要把私有包的
name和version写死在repositories里——那是package类型干的事,和vcs冲突
auth.json 必须放在 HOME 目录,且权限要设为 600
用 HTTPS 克隆私有仓库时,Composer 依赖 auth.json 提供 token 或密码。但这个文件的位置和权限极易出错:放错位置(比如放在项目根目录)或权限太宽(如 644),Composer 会静默忽略它,然后卡在认证失败或提示 Failed to clone https://...。
- 标准路径是
~/.composer/auth.json(Linux/macOS)或%APPDATA%\Composer\auth.json(Windows) - 内容格式必须严格:
{ "http-basic": { "gitlab.example.com": { "username": "token", "password": "glpat-xxxxxx" } }, "github-oauth": { "github.com": "ghp_xxx..." } } - 执行
chmod 600 ~/.composer/auth.json(macOS/Linux),否则 Composer 拒绝读取
私有包的 composer.json 必须含 name 和稳定 version 标签
你的私有库本身也得“像个包”,否则 Composer 解析时会找不到匹配项。常见错误是开发完直接 push,但没打 tag 或 composer.json 缺关键字段,结果 composer require org/private-lib 报 no matching package found。
-
name字段必须全局唯一,格式为vendor/name(如acme/utils),且要和你在require中写的完全一致 - 版本必须通过 Git tag 发布:运行
git tag v1.0.0→git push origin v1.0.0;dev-main分支可临时用,但生产环境强烈建议用语义化 tag - 确保 tag 对应的 commit 里,
composer.json的version字段**不要填写**——Composer 会自动从 tag 名推导,填了反而可能冲突
使用 composer config --global repositories.xxx 会覆盖项目级配置
有人想“一劳永逸”地把私有源加到全局,用 composer config --global repositories.mylib '{"type": "vcs", "url": "..."}',结果发现项目里 composer install 拉的不是自己期望的版本,甚至出现依赖冲突。这是因为全局 repositories 会合并进每个项目的加载顺序,优先级高于 Packagist,但低于项目 composer.json 自己定义的 repositories —— 而且一旦全局配置存在,项目里删掉对应源也不会生效。
- 推荐始终在项目级
composer.json的repositories中声明私有源,清晰、可追踪、不污染全局 - 如果多个项目共用同一私有源,考虑用 Composer 的
config+repositories组合,或用私有 Packagist 镜像(如 Satis / Private Packagist),而不是靠全局配置“偷懒” - 检查当前生效的源列表:运行
composer config --list | grep repositories,确认没有意外的全局源干扰
auth.json 权限不对、tag 没推上去,或者以为全局配置能“继承”却忘了它实际是叠加而非替代。每一步都得单独验证,别假设上一步成功就代表这一步也通。


















