前言
我们把自研的制品仓库项目 kkRepo 开源了。
它的定位很直接:做一个面向 Sonatype Nexus Repository 迁移场景的开源平替项目,在用户可见的客户端协议、权限模型和 /repository/<repo>/... URL 布局上尽量兼容,同时把运行时架构换成更适合云原生、多副本和对象存储的形态。
项目地址:
从 nexus-plus 到 kkRepo
这个项目最早叫 nexus-plus。名字很直白:我们想做的是一个兼容 Nexus 使用习惯、但在存储、部署和迁移上更适合我们自身场景的增强实现。
后来我们收到了来自 Nexus 相关商标权益方的商标侵权提醒邮件。这个提醒也让我们重新审视了项目命名:作为一个独立开源项目,我们应该避免把兼容目标写成自己的品牌,更应该清楚地区分 “兼容 Sonatype Nexus Repository 的用户可见行为” 和 “项目本身的身份”。 
所以,nexus-plus 改名为 kkRepo。
我们仍然会在文档中提到 Sonatype Nexus Repository,但只用于说明兼容性、迁移路径和互操作行为。kkRepo 是独立开源项目,不隶属于 Sonatype, Inc.,也未获得其认可、赞助或背书。
为什么要重新做一个制品仓库
制品仓库听起来不是一个 “令人兴奋” 的项目,但它是公司工程体系里非常关键的一层基础设施。Maven、npm、PyPI、Go、Helm、Docker、NuGet、RubyGems、Yum 等生态里的包,都可能每天被 CI/CD 和开发环境高频读取。
我们长期使用 Sonatype Nexus Repository。随着规模增长,几个问题变得越来越明显:
- 老版本部署依赖 OrientDB、本地数据目录等状态,故障恢复和升级风险比较高。
- 需要更明确的多副本部署能力、滚动升级能力和弹性扩容能力。
- 元数据、权限、token、审计和迁移状态需要落在可治理、可备份、可排查的外部数据库里。
- blob 数据更适合放在 OSS/S3 这类对象存储中,而不是绑定在单个本地目录上。
- 迁移新系统时,客户端配置最好不要大规模修改,否则会影响大量构建任务和业务线。
我们并不是想复制 Nexus 的内部实现。kkRepo 选择的是另一条路线:兼容用户能感知到的行为,重写我们真正需要的运行时架构。
kkRepo 的核心设计
kkRepo 是一个 Java / Spring Boot 实现的自托管制品仓库,当前支持:
- Maven
- npm
- PyPI
- Go module proxy
- Helm
- Docker / OCI Registry
- NuGet
- RubyGems
- Yum
- Raw
它的几个核心设计取舍是:
- MySQL-first:仓库、component、asset、权限、用户、角色、token、session、审计、迁移状态和可重建索引都存储在 MySQL。
- OSS/S3-first:大 blob 存储在 OSS/S3 兼容对象存储中,MySQL 只保存引用、checksum、大小和 content type 等元数据。
- 多副本优先:session、认证 ticket、catalog 水位、迁移进度、短生命周期协同状态都放在共享存储中,进程内缓存只作为可重建热缓存。
- 客户端兼容优先:保留
/repository/<repo>/...URL 布局,尽量复用现有 Maven settings、npm registry、PyPI index-url、Go proxy、Helm repo 等客户端配置。 - 迁移是产品能力:不是一次性脚本,而是后台可操作、可 preflight、可续跑、可重试、可校验的迁移流程。
也就是说,kkRepo 不依赖 OrientDB、内嵌 Elasticsearch、Karaf、OSGi 或本地持久化 blob 文件系统作为生产运行时基础。
对迁移用户来说,重点是少改配置
kkRepo 最关心的不是 “做一个全新的制品仓库体验”,而是让已有 Nexus Repository 用户能平滑迁移。
典型迁移流程是:
- 在 kkRepo 管理后台配置源 Sonatype Nexus Repository 地址和账号。
- 先执行元数据 preflight,检查源端版本、权限、脚本能力、repository、blob store、用户、角色和权限数据。
- 迁移用户、角色、权限、blob store 和 repository 定义。
- 扫描 hosted 仓库资产,生成迁移任务。
- 迁移真实 package/blob 数据到 kkRepo。
- 上线前执行增量同步。
- 最后把原制品仓库域名指向 kkRepo。
对于 Maven、npm、PyPI、Go、Helm、NuGet、RubyGems、Yum 和 Raw 这类非 Docker 客户端,目标是继续使用原来的 /repository/<repo>/... 地址形态。Docker / OCI 则保持 Registry HTTP API V2 的 /v2/... 入口、仓库名和 connector/path-based routing 形态一致。
我们内部已经完成过 0 停机迁移:域名切换后,客户端配置不需要修改,CI 继续沿用原来的 registry、settings 和 index 配置。
为什么说它更适合云原生部署
很多制品仓库的痛点不在 “能不能上传下载包”,而在出问题时能不能恢复、扩容时能不能横向加副本、升级时能不能滚动发布。
kkRepo 从一开始就按多副本设计:
- 任意应用副本都可以处理仓库请求。
- 正确性不依赖单个 JVM 的内存状态。
- 进程内缓存丢失后可以自动回暖。
- 后台迁移和任务状态持久化在 MySQL 中。
- blob 内容在 OSS/S3 中,应用节点不需要绑定持久化本地磁盘。
- 指标、健康检查和管理后台面向运维可见。
这对把制品仓库跑在 Kubernetes、ECS 或其它弹性基础设施上的团队会更友好。
AI 参与开发,但验证不能靠感觉
kkRepo 是在 AI 编程助手帮助下完成的项目。主体代码由 AI 在较短时间内完成,人主要负责产品目标、架构边界、兼容性要求、问题定位和 Review。
但基础设施项目不能靠 “看起来实现了” 来上线。
所以 kkRepo 把验证放在很高的位置:
- 项目内有独立的
compat-test模块,面向真实 Sonatype Nexus Repository 参考实例做黑盒兼容性测试。 - 协议行为会对比 HTTP 状态、关键 header、响应体语义、checksum、metadata 和真实客户端行为。
- 迁移过程支持 preflight、resume、retry、checksum 校验和报告。
- 对多副本相关状态,默认要求落 MySQL 或其它共享协调机制,进程内缓存只允许作为可恢复优化。
AI 可以提高实现速度,但兼容性和生产可用性必须靠测试、真实流量和可观测性来兜底。
什么场景适合试试 kkRepo
如果你正在使用 Sonatype Nexus Repository,并且遇到下面这些问题,kkRepo 可能值得看一眼:
- 老版本实例升级困难,担心 OrientDB、内嵌 Elasticsearch 或本地数据目录带来的恢复风险。
- 现有制品规模和访问量已经超出小团队部署形态。
- 希望把核心状态放到 MySQL,把 blob 放到 OSS/S3。
- 希望制品仓库支持多副本、滚动升级和更清晰的故障恢复。
- 希望从现有 Nexus Repository 迁移时尽量不改客户端配置。
- 希望迁移过程可视化、可续跑、可重试,而不是靠临时脚本赌一次。
如果你的团队规模很小,制品数量和请求量都不高,并且现有 Nexus Repository 部署稳定可控,那继续使用现有方案也完全合理。kkRepo 更适合那些已经把制品仓库当成核心基础设施,并且开始认真关心高可用、扩容、迁移和恢复能力的团队。
快速试用
本地可以用 quickstart 脚本启动一个试用环境:
curl -fsSL https://raw.githubusercontent.com/klboke/kkrepo/main/scripts/quickstart.sh | bash
启动后访问:
- 管理控制台:
http://127.0.0.1:19090/admin/ - 用户侧浏览器:
http://127.0.0.1:19090/browse/ - 健康检查:
http://127.0.0.1:19091/actuator/health
quickstart 默认使用本地 File blob storage,适合试用和开发。生产环境建议使用 OSS/S3,并替换默认 secret、密码和部署参数。
开源之后
kkRepo 目前已经开源,许可证是 Apache License 2.0。
接下来我们会继续完善:
- 更多协议兼容性测试。
- 更完整的迁移报告和失败诊断。
- 更多仓库格式支持,例如 APT / Debian、Cargo、Terraform Provider / Module Registry、Conan、Conda、Composer 等。
- 生产部署、监控、备份恢复和安全加固文档。
- 与真实用户场景相关的兼容差异修复。
如果你也在维护制品仓库,或者正在考虑从旧 Nexus Repository 部署迁移,欢迎试用 kkRepo、提交 issue、补充兼容性反馈,或者直接参与贡献。
项目地址:
https://github.com/klboke/kkrepo
kkRepo 的目标不是重新发明一个更复杂的 Nexus,而是给需要迁移、需要多副本、需要 MySQL 和 OSS/S3 架构的团队,一个更简单、更可控、更容易恢复的开源选择.

