私有 GitLab 仓库必须用 vcs 类型并配合 auth.json 配置 token,不可走 Composer 镜像源;镜像仅缓存 packagist.org 公开包,对私有包无感知,混用配置将导致 404 或克隆失败。

私有 GitLab 仓库必须用 vcs 类型,不能走镜像源
Composer 中文镜像(如阿里云 https://mirrors.aliyun.com/composer/)只缓存 packagist.org 公开包,对局域网 GitLab 上的 myorg/internal-sdk 这类私有包完全无感知。一旦把私有源写成 "type": "composer" 并指向镜像地址,Composer 就会尝试拉取不存在的 packages.json,结果必然是 404 或 Could not find package。
常见错误操作包括:
- 把
"url": "https://gitlab.internal.corp"改成"url": "https://mirrors.aliyun.com/composer/" - 全局禁用官方源:
"packagist.org": false—— 这只会切断 fallback,不加速私有源,也不解决认证 - 误以为加了镜像后
composer require internal/auth-sdk就能自动走 CDN,实际仍卡在Cloning into '...'
正确做法是:私有 GitLab 包必须声明为 vcs 类型,并通过 auth.json 注入 token;二者不共用同一套配置机制,不能互相替代。
auth.json 必须放对位置且权限完整
auth.json 文件必须放在用户主目录下,路径因系统而异:
- Linux/macOS:
~/.composer/auth.json - Windows:
%APPDATA%\Composer\auth.json
内容格式必须严格为:
{"gitlab-token": {"gitlab.internal.corp": "glpat-xxxxxxxx"}}
其中 glpat-xxxxxxxx 是 GitLab 生成的 Personal Access Token,权限必须同时勾选:
-
read_api(用于获取项目元数据) -
read_repository(用于克隆代码)
不要用 http-basic 配私有 GitLab 源——它只对 type: composer 源生效,对 vcs 无效。
项目级 repositories 需按顺序声明,且不能删掉默认源
在项目 composer.json 的 repositories 数组中,必须按如下顺序组织:
- 第一项:显式禁用硬编码兜底源 ——
{"packagist.org": false}(注意不是"packagist": false) - 第二项:镜像源 ——
{"type": "composer", "url": "https://mirrors.aliyun.com/composer/"}(URL 末尾必须带/) - 后续项:私有
vcs源 ——{"type": "vcs", "url": "https://gitlab.internal.corp/myorg/pkg.git"}(必须带.git后缀)
关键点:
-
repositories必须是数组,写成对象会被忽略 - 不能把
packagist.org禁用和镜像源合并成一项,否则无效 - 保留
packagist.org作为 fallback 是安全底线:私有源临时不可用时,公共包仍可装
改完后必须执行:rm -rf vendor composer.lock && composer install —— composer update 会复用旧 lock 中的 dist URL,无法触发新镜像元数据拉取。
GitLab CI 中镜像配置必须由 runner 用户当场执行
在 .gitlab-ci.yml 中,composer config -g 命令若在本地配好再提交脚本,几乎必然失效。根本原因是:CI job 默认以 runner 用户运行,而你本地用 root 或其他用户执行的 config -g 写进了错误路径(如 /root/.composer/config.json),runner 用户根本读不到。
正确做法是在 CI 脚本中直接注入:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ composer config -g --unset github-protocols
注意:
-
-g不能省,否则只改当前目录下的composer.json,对后续install无影响 - URL 末尾
/必须存在,否则拼出的packages.json路径会 404,触发静默 fallback -
github-protocols默认含ssh,CI 环境通常没 SSH key,关掉可避免卡在 Git clone
验证是否生效:composer config -g repo.packagist 输出应为完整 JSON,不是 null 或空行。
局域网 GitLab 和镜像源是两套独立系统,混用配置是最常踩的坑。镜像只管公开包元数据,私有包只认 vcs + auth.json,连缓存路径、认证方式、URL 格式都完全不同——强行统一反而全崩。


















