toran proxy停更后本地packagist镜像难搭,因官方无镜像接口,只能代理缓存;composer-proxy是最佳替代,支持v2协议、自动缓存元数据与zip包、无需数据库,但需禁用默认packagist.org才能正常工作。

为什么 Toran Proxy 停更后,本地 Packagist 镜像难搭
因为 Packagist 官方不提供镜像接口,所有“本地镜像”本质是代理 + 缓存服务,不是单纯 rsync 同步。Toran Proxy 停更后,packagist-mirror、satis 这类工具要么只支持静态生成(无法实时同步新包)、要么依赖已废弃的 Packagist v1 API。真正能替代 Toran 的,只剩 composer-proxy(Go 写的轻量代理)或自建 artifactory / nexus —— 但后者配置重、资源消耗高。
用 composer-proxy 搭建最小可用镜像(推荐)
composer-proxy 是目前最接近 Toran 行为的开源替代:支持 Composer v2 协议、自动缓存元数据和 ZIP 包、可配置上游(支持 packagist.org 或私有 repo)、无需数据库。它不生成静态 JSON,而是实时响应 composer install 的 HTTP 请求,行为最贴近原生体验。
实操建议:
- 从 GitHub 下载最新
composer-proxy二进制(不要用go install,官方未发布模块路径) - 启动时指定缓存目录和监听地址:
./composer-proxy -cache-dir ./cache -listen :8080 -upstream https://packagist.org - 在项目
composer.json中配置仓库:"repositories": [{"type": "composer", "url": "http://localhost:8080"}] - 首次请求会慢(要拉取并缓存 meta),后续同包安装快于直连,因 ZIP 包也落盘缓存
常见错误:镜像能访问但 composer install 报 404 或 “package not found”
这不是网络问题,而是 Composer 默认只信任 packagist.org。即使你配了本地仓库,它仍会向 packagist.org 查包名是否合法(v2 协议的 packages.json 元数据校验逻辑强制走官方)。
必须加这个开关才能绕过:
- 全局禁用 packagist.org:运行
composer config -g repo.packagist false - 或在项目中显式关闭:
composer config repo.packagist false - 否则
composer install会先尝试访问https://packagist.org/p2/xxx.json,失败后才 fallback 到你的镜像 —— 但 fallback 逻辑在 v2 中已被弱化,多数情况直接报错
性能与兼容性注意点
composer-proxy 默认不校验包签名(Packagist 的 providers-api 签名机制),所以如果你启用了 composer config secure-http true 或使用了企业级安全策略,需额外加 -insecure 启动参数,否则部分 HTTPS 跳转会失败。
缓存策略也影响体验:
- meta 数据(
packages.json)默认缓存 1 小时,新发布的包最多延迟 60 分钟可见 - ZIP 包永久缓存,但不会自动清理 —— 需定期
find ./cache -name "*.zip" -mtime +30 -delete - 不支持
composer outdated的远程比对(它依赖 packagist.org 的完整索引),只能用于install/update
真正麻烦的是私有包混用场景:如果同时配了 packagist.org(false)+ 私有 Git repo,Composer 会把所有包都丢给私有 repo 解析,导致公开包 404 —— 此时必须用 composer config --merge repos.foo {"type":"composer","url":"http://your-mirror"} 显式声明镜像优先级,不能靠顺序。










