在 composer.json 的 repositories 字段中显式配置私有仓库:git 仓库用 "type": "vcs" + https/ssh 地址,composer 专用仓库用 "type": "composer" + 服务根 url;需配置认证(oauth token 或 ssh)、确保包名版本正确、避免 packagist 源前置,并注意仓库匹配顺序。

怎么在 composer.json 里加私有仓库
私有包不能靠 Packagist 自动发现,必须显式告诉 Composer 去哪找。核心是往 composer.json 的 repositories 字段里加一条配置,类型取决于你用的托管方式。
- Git 仓库(如自建 GitLab、GitHub 私有库):用
"type": "vcs","url"填完整 HTTPS 或 SSH 地址(如https://git.example.com/myorg/my-package.git) - Composer 专用仓库(如 Satis、Private Packagist):用
"type": "composer","url"填该服务的根地址(如https://repo.mycompany.com),它得能返回packages.json - 不要混用
vcs和composer类型去指向同一个 Git 仓库——Composer 会优先走vcs,但可能跳过你配的认证或镜像逻辑
为什么 composer install 报 “Could not fetch” 或 “401”
这基本是认证没通。Composer 访问私有仓库时,默认不带凭据,尤其 HTTPS 方式下需要显式提供。
- Git over HTTPS:运行
composer config -g github-oauth.github.com <token></token>(GitHub)或composer config -g gitlab-token.gitlab.example.com <token></token>(GitLab),token 需有read_api或read_repository权限 - Git over SSH:确保本地
~/.ssh/id_rsa已添加到对应 Git 服务,且url写成git@git.example.com:myorg/my-package.git(不是 HTTPS) - 公司内网仓库若需代理:设环境变量
COMPOSER_HTTP_PROXY,别只配系统级 proxy——Composer 不读http_proxy
composer require 找不到私有包怎么办
即使仓库配对了,Composer 默认只从 Packagist 拉包。私有包必须“声明可见”,否则 require 会直接报 Could not find package。
- 确认私有包的
name(如myorg/my-package)和version(如dev-main或1.0.0)在它的composer.json里写对了,且已推送到远程分支或打过 tag - 如果用的是
vcs类型仓库,Composer 只索引默认分支(通常是main或master)的composer.json;想用dev-feature/x分支,得在require时显式写版本:composer require myorg/my-package:dev-feature/x - 运行
composer clear-cache再试——旧缓存可能记着“这个包不存在”
私有仓库配置的坑:全局 vs 项目级、顺序与覆盖
repositories 列表不是越靠后越优先,而是从上到下扫描,第一个匹配的就用。这点极易被忽略。
- 项目级
composer.json里的repositories会覆盖全局配置(~/.composer/config.json),不是叠加——删掉项目里的,才会回落到全局 - 别把 Packagist 官方源(
{"type": "packagist", "url": "https://packagist.org"})放在列表最前面:它会拦截所有请求,导致私有包根本没机会被查到。官方源应放最后,或干脆删掉(Composer 2.2+ 默认内置,无需显式声明) - 多个私有仓库同名包冲突时,谁排第一谁生效。比如两个 Git 仓库都提供了
myorg/utils,但分支不同,靠位置决定用哪个
最麻烦的其实是团队协作时仓库地址硬编码在 composer.json 里——有人换网络、换 Git 服务商,就得改代码。真要长期维护,建议用 composer config repositories.x.url 动态覆盖,或者让 CI 环境注入变量。










