如何优雅地处理一个Composer包从公共仓库变为私有? (仓库迁移)

12次阅读

私有包必须显式配置repositories,禁用packagist.org,重建composer.lock,并确保git仓库tag可访问。否则会因回退公共源或锁文件失效导致安装失败。

如何优雅地处理一个Composer包从公共仓库变为私有? (仓库迁移)

composer.json 中的 repositories 配置必须显式声明私有源

Composer 不会自动 fallback 到私有仓库,哪怕你已用 composer config repositories.xxx 添加过。项目级 composer.jsonrepositories 字段必须包含该包所在私有源,否则 composer install 仍会尝试从 packagist.org 拉取——此时若包已移除,直接报错 Could not find package xxx at version yyy

实操建议:

  • 将私有 Git 仓库(如 gitlabgithub private、自建 gitea)以 vcs 类型写入 repositories,URL 必须带认证信息或依赖 ssh key
  • 若使用私有 Packagist 服务(如 Satis、Private Packagist),则用 composer 类型,并确保 packagist.org 被显式禁用(见下一条)
  • 避免混用多个同名包源;Composer 默认按数组顺序查找,但冲突时行为不可靠

必须禁用 packagist.org 防止意外回退

即使你在 repositories 里加了私有源,Composer 默认仍会把 packagist.org 当作兜底源。一旦私有源中缺少某个版本(比如只同步了 dev-main,没同步 v1.2.3),它就会去公共源找——而这时包已下架,报错 Could not find package xxx at version v1.2.3

正确做法是显式关闭默认源:

{     "repositories": [         {             "type": "composer",             "url": "https://your-private-packagist.com"         },         {             "packagist.org": false         }     ] }

注意:{"packagist.org": false} 是一个特殊语法,必须作为独立对象放在 repositories 数组末尾,不能合并进其他源配置。

composer.lock 文件必须重生成,不能复用旧锁

composer.lock 里记录的是包在 packagist.org 上的 dist URL、commit hash 和镜像校验值。迁移到私有源后,这些字段全部失效:dist URL 不可达、hash 可能因打包方式不同而变、甚至 commit hash 在私有仓库里可能被 force-push 覆盖。

安全做法是彻底重建锁文件:

  • 删掉现有 composer.lock
  • 运行 composer update --lock(推荐)或 composer install(仅当 composer.json 已完整适配私有源)
  • 检查新锁文件中 packages 下该包的 source.type 是否为 gitpackagesource.url 是否指向私有地址

跳过这步会导致 CI 构建失败、本地环境与生产不一致,且错误信息模糊(常表现为 “corrupted zip” 或 “invalid signature”)。

私有 Git 仓库需确保 tag/branch 可被 Composer 解析

Composer 依赖 Git 的 ls-remotearchive 接口解析版本。如果私有仓库未启用 Git HTTP 服务(如 nginx 未配置 git-http-backend),或 SSH 端口防火墙拦截,composer update 会卡在 Loading composer repositories with package information 或报错 Failed to execute git clone

验证方法:

  • 手动执行 git ls-remote --tags --refs https://your-git/repo.git(HTTP)或 git ls-remote --tags --refs git@your-git:repo.git(SSH)
  • 确认返回结果含有效 tag(如 refs/tags/v1.2.3),而非空或权限拒绝
  • 若用 HTTPS,确保 auth.json 正确配置 Token;若用 SSH,确保 ~/.ssh/config 匹配仓库域名且 key 已加载

GitLab/GitHub 私有库常见坑:token 缺少 read_package_registry 权限(GitLab)或 packages:read(GitHub),导致 API 返回 403 却被 Composer 静默忽略为“无此包”。

text=ZqhQzanResources