composer要拉取gitlab私有包,必须同时满足三件事:在composer.json顶层声明type为"vcs"的仓库、在~/.composer/auth.json中配置匹配域名的personal access token(chmod 600)、require的包名与私有库composer.json中的name字段逐字符一致。

Composer 要拉到 GitLab 私有包,光写 require 不行,必须同时满足三件事:在 composer.json 里声明 vcs 类型仓库、用 auth.json 配好对应域名的 Personal Access Token、私有包自身的 name 字段和 require 中写的包名**逐字符一致**。少一个,composer install 就会静默跳过或报 Could not find package。
repositories 必须是顶层字段且 type 为 vcs
Composer 不会自动扫描 URL,也不会从网页地址推导 Git 地址。它只认你明确定义的源。
-
repositories必须写在composer.json最外层,不能嵌套在config、scripts或其他字段下 - 每条仓库配置必须含
"type": "vcs"—— 写成"package"或漏掉这一行,Composer 就当它不存在 -
url必须是可直接git clone的地址,结尾带.git,例如https://gitlab.example.com/group/my-pkg.git;写成https://gitlab.example.com/group/my-pkg(缺后缀)会触发No valid composer.json was found - 如果 GitLab 启用了子路径(如
/gitlab),URL 中也得带上,否则 API 请求失败
auth.json 必须放对位置、格式严格匹配
GitLab 不接受用户名密码直传,也不读 .netrc,只认 auth.json 里的 http-basic 结构,且域名必须完全一致(含端口、不含协议)。
- 文件路径只能是
~/.composer/auth.json(全局)或项目根目录的./auth.json;放在vendor/或子目录下无效 - 权限必须是
600:chmod 600 ~/.composer/auth.json,否则 Composer 直接忽略 -
username填oauth2(GitLab 约定,不是你的账号名),password填完整的 PAT(glpat-...),不能是 token 名或密码 - 域名键名要和
repositories.url中的 host 完全一致,比如gitlab.example.com:8443和gitlab.example.com是两个不同域,需分别配置
require 包名必须和私有库 composer.json 的 name 字段完全一致
Composer 不按 Git 路径匹配,只严格比对 name 字段。差一个字母、大小写、斜杠方向,都会失败。
- 假设私有库根目录
composer.json里写的是{"name": "acme/utils"},那主项目的require就必须是"acme/utils": "dev-main" - 不能写成
"Acme/utils"、"acme-utils"、"acme/utils-dev",也不能省略 vendor 段 - 分支必须用
dev-前缀,如dev-main、dev-develop;写"main"或"*"会被当成模糊约束,去 Packagist 查,查不到就报错 - 私有库自身若没
name字段,Composer 会拒绝加载,且不报明确错误,只表现为“找不到包”
HTTPS 还是 SSH?选哪个更稳
HTTPS 更适合 CI/CD,SSH 更适合本地开发,但两者认证机制完全不同,不能混用。
- HTTPS 方式依赖
auth.json+ PAT,Token 必须有read_repository权限;禁用双因素(2FA)时仍可用,但启用后 PAT 是唯一方式 - SSH 方式不走
auth.json,靠系统ssh-agent和 GitLab 上绑定的 Deploy Key;验证是否生效:运行ssh -T git@gitlab.example.com,返回Welcome to GitLab才算通 - CI 环境中用 SSH 要特别注意:GitLab CI 默认用
CI_SERVER_URL解析域名,确保composer.json中的urlhost 和 Deploy Key 绑定的 host 完全一致 - 别在同一个项目里混用 HTTPS 和 SSH 地址——Composer 不会自动降级或切换协议,出错时排查路径会变复杂
最容易被忽略的是:私有包自己的 composer.json 里没有 name 字段,或者 repositories 被不小心缩进到了 config 下面。这两个问题不会报错提示,只会让 composer install 完全无视该仓库——看起来像网络问题,其实是配置结构错了。











