私有仓库需在composer.json中配置repositories字段并设type为vcs;认证失败优先检查auth.json位置与格式;安装失败常因minimum-stability限制,需设为dev或配置branch-alias;ci中须通过环境变量composer_auth注入认证信息。

私有仓库必须配置 repositories 字段
Composer 默认只认 Packagist,想装 GitLab 或 Bitbucket 上的包,光写 "vendor/name": "dev-main" 没用——它根本找不到源。必须在 composer.json 顶层显式声明仓库地址和类型。
GitLab 和 Bitbucket 都属于 VCS 类型,填 "type": "vcs" 即可,不需要额外插件或服务端配置:
{
"repositories": [
{
"type": "vcs",
"url": "https://gitlab.example.com/group/project.git"
}
],
"require": {
"group/project": "dev-main"
}
}
注意:url 必须是完整 Git 克隆地址(含 .git 后缀),不能是网页 URL;require 中的包名要和仓库里 composer.json 的 name 字段严格一致,大小写都不能错。
认证失败时优先检查 auth.json 格式
私有仓库拉取失败,90% 是认证问题,错误信息通常是 Could not fetch https://gitlab.example.com/...: Failed to execute git clone... 或更隐晦的 401 Unauthorized。别急着改 SSH 密钥,先确认 auth.json 是否放对位置、格式是否合法。
auth.json 必须放在 Composer 的配置目录下(COMPOSER_HOME,通常是 ~/.composer/auth.json),内容要严格匹配域名和凭据类型:
- GitLab 推荐用 Personal Access Token,
token字段填完整 token 值(不是名字) - Bitbucket Cloud 要用 App Password(不是账号密码),且
username必须是 Bitbucket 用户名,password是生成的 App Password - 所有字段名必须小写,不能写成
Token或USERNAME
示例(GitLab):
{
"http-basic": {
"gitlab.example.com": {
"username": "gitlab-ci-token",
"password": "glpat-xxxxxxxxxxxxxxxxxxxx"
}
}
}
composer install 不拉私有包?检查 minimum-stability 和分支别名
即使仓库和认证都对了,composer install 还是跳过私有包,大概率是稳定性约束卡住了。Composer 默认只接受 stable 版本,而私有仓库往往只有 dev-main 或 dev-develop 分支。
两个办法任选其一:
- 临时放宽:加
--prefer-lowest或--ignore-platform-reqs不解决问题,得改minimum-stability为dev,同时给分支加branch-alias - 更稳妥:在私有包自己的
composer.json里声明别名,比如"dev-main": "1.0.x-dev",然后主项目直接 require"group/project": "^1.0"
别 alias 错分支名——dev-main 对应的是 Git 分支名,不是 main 或 master,大小写敏感,且不能带 origin/ 前缀。
GitLab CI 中使用私有包需手动注入 COMPOSER_AUTH
本地能装,CI 里报 401,是因为 CI 环境没读到 auth.json。GitLab CI 不自动加载用户家目录下的配置,必须把认证信息转成环境变量传进去。
安全做法是用 GitLab 的 CI/CD Variables 功能,创建变量 COMPOSER_AUTH,值为 JSON 字符串(注意转义双引号):
{"http-basic":{"gitlab.example.com":{"username":"gitlab-ci-token","password":"glpat-..."}}}
然后在 .gitlab-ci.yml 里确保 composer install 执行前该变量已生效。别把 token 写进 auth.json 提交到仓库,也别在脚本里 echo 出来——CI 日志默认公开可查。
Bitbucket Pipelines 同理,用 environment 块注入 COMPOSER_AUTH,但要注意它的变量值不支持换行,JSON 必须压成单行。










