私有GitLab仓库必须配置为vcs类型源并用Deploy Token认证,不可用dist源;URL须以.git结尾,Token应通过COMPOSER_AUTH环境变量注入,避免硬编码。

私有GitLab仓库必须配置为VCS类型源,不能用dist
Composer默认把GitLab仓库当作dist源(即下载预打包的zip/tar),但私有项目通常没启用Package Registry或没发布dist包。直接运行composer install会报Could not fetch https://gitlab.example.com/api/v4/projects/xxx/repository/archive.zip?sha=...——这是因为它在尝试走API下载,而私有库不开放匿名API访问。
正确做法是显式声明为vcs类型源,让Composer走git clone流程,后续才能注入Deploy Token认证:
{
"repositories": [
{
"type": "vcs",
"url": "https://gitlab.example.com/group/project.git"
}
]
}
注意:url必须以.git结尾,否则Composer无法识别为Git仓库。
Deploy Token需拼在Git URL里,且仅限HTTPS协议
GitLab Deploy Token本质是HTTP Basic Auth凭证,只能用于HTTPS克隆,不能用于SSH。把它塞进composer.json的repositories.url里是最直接的方式:
{
"repositories": [
{
"type": "vcs",
"url": "https://deploy-token-123:abc456def789@gitlab.example.com/group/project.git"
}
]
}
-
deploy-token-123是Token用户名,abc456def789是Token值,两者用冒号连接后Base64编码?不需要——Composer原样传给Git,Git自己处理Basic Auth - Token必须有
read_repository权限,read_package_registry无关(那是给CI拉Composer包用的) - 别把Token硬编码进
composer.json提交到Git——应通过环境变量注入,下文说明
用COMPOSER_AUTH环境变量避免明文泄露
把Deploy Token写死在composer.json里等于公开密钥。正确姿势是用COMPOSER_AUTH环境变量集中管理认证信息:
export COMPOSER_AUTH='{"http-basic":{"gitlab.example.com":{"username":"deploy-token-123","password":"abc456def789"}}}'
composer install
这个JSON结构告诉Composer:当访问gitlab.example.com域名下的任何HTTPS Git地址时,自动带上Basic Auth头。它比URL内嵌更安全,也支持多个GitLab实例共存。
- CI环境中(如GitLab CI),直接在
.gitlab-ci.yml里设variables即可 - 本地开发可写入
~/.composer/auth.json,但注意该文件权限必须是600,否则Composer会拒绝读取 - 如果GitLab启用了双因素认证(2FA),Deploy Token仍可用——它不走用户登录流
常见失败原因:Git子模块、subtree或自定义install-path干扰
当项目含Git子模块,或composer.json里配了"type": "project" + "install-path",Composer可能绕过COMPOSER_AUTH,回退到系统Git凭据管理器(如git-credential-manager),导致认证失败。
验证方式:运行composer install -vvv,看日志里是否出现Cloning [url] via git clone,以及是否有Failed to clone ... could not read Username类错误。
- 临时解决:执行
git config --global credential.helper ''禁用全局凭据助手 - 根本解决:确保所有私有依赖都声明为
vcs源,且不依赖Git子模块做依赖管理 - 若必须用子模块,改用
post-install-cmd脚本手动git submodule update --init,并提前用git config配好Deploy Token
Deploy Token不是万能钥匙——它只对git clone生效,对git pull、git submodule或git archive等操作无透传能力,这点容易被忽略。


















