ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Nexus 3.50.0 Windows部署与制品管理实战:从解压到上传npm/Maven包

Nexus 3.50.0 Windows部署与制品管理实战:从解压到上传npm/Maven包

简介:Nexus Repository Manager 3.50.0-01 是面向 Windows 64 位系统的仓库管理软件,主要服务于需要搭建 Maven 私服、统一管理构建产物的软件开发团队与运维人员。它支持 Maven、npm、Docker 等多种构建工具,可集中存储与发布软件包,并通过细粒度权限控制保障仓库内容的完整性与安全性,同时优化了存储和检索速度,提升构建部署效率。压缩包共 690 个文件,约 240.15MB,以 419 个 jar 核心库、82 个 dll 动态链接库、22 个 exe 可执行程序为主,另含 xml、properties、cfg 等配置文件和少量 png、gif 图标资源,目录结构完整,开箱即可部署。已有 494 人学习下载。对于想搭建私有仓库、规范依赖管理或排查仓库权限与性能问题的读者,这份安装包提供了可直接落地的运行环境,便于快速验证私服搭建流程与配置细节。

1. 拿到 nexus-3.50.0-01-win64.zip 之后:它到底是什么、谁该装

很多人第一次看到nexus-3.50.0-01-win64.zip这个文件名,会下意识把它和桌面美化工具 Nexus Dock 混在一起,毕竟热搜里「nexus桌面美化官网」的搜索量一直不低。但只要你打开压缩包,看到bin、etc、lib、sonatype-work这套目录结构,就会明白这是 Sonatype Nexus Repository Manager 3 的 Windows 64 位发行包,一个跑在内网、用来托管 Maven、npm、Docker、PyPI 等制品的私有仓库服务端。它解决的核心问题很具体:团队里几十号人反复从公网拉依赖,慢、断、被墙、版本漂移,甚至某天上游把某个老版本删了,你的构建直接挂掉。把 Nexus 架在内网,所有依赖先过它一手,构建速度和可复现性立刻不一样。这篇面向的是手里已经拿到这个 zip、准备在 Windows 上把它跑起来并真正用起来的后端、DevOps 和构建工程师,也适合被「npm 怎么把组件上传 nexus repository 区分版本」这类问题卡住的同学。下面从解压、启动、建仓库到上传制品,一步步走完。

2. 解压与首次启动:把 zip 变成一个能访问的服务

2.1 为什么 Nexus 3 在 Windows 上推荐用 zip 而不是安装器

Nexus 3 官方在 Windows 上提供两种形态:一种是.exe安装器,会注册成 Windows 服务;另一种就是nexus-3.50.0-01-win64.zip这种绿色压缩包。我一般优先选 zip,原因有三个。第一,安装器会把路径写进注册表和服务配置,升级或迁移时清理麻烦,而 zip 解压即用,删目录就等于卸载。第二,zip 形态对目录权限的要求更透明,出问题能直接看到是哪个目录没写权限。第三,团队里经常要在一台机器上并存多个版本做验证,zip 天然支持多实例。代价是它不会自动开机自启,需要你自己用sc或 NSSM 注册服务,这点后面会讲。

解压时有个高频翻车点:不要解压到带中文或空格的路径。Nexus 内部有脚本会拼接路径,遇到空格或非 ASCII 字符时,nexus.vmoptions里的-Dkaraf.data之类参数容易解析异常,表现为启动到一半卡住或直接报找不到主类。我习惯固定放在D:\nexus\下,路径短、无空格。

2.2 解压后的目录结构与两个关键目录

解压完你会看到两个顶层目录,这是理解 Nexus 运维的关键:

目录作用是否随版本升级替换
nexus-3.50.0-01/程序本体,含bin、etc、lib是,升级时整个替换
sonatype-work/数据目录,含仓库内容、配置、日志、索引否,升级时必须保留

很多人升级时把整个解压目录覆盖掉,结果仓库数据全没了,这就是没分清这两个目录。sonatype-work才是你的命根子,备份策略应该围绕它做,而不是围绕程序目录。

2.3 用命令行启动并验证端口

进入bin目录,用管理员权限打开 PowerShell 或 CMD:

cd D:\nexus\nexus-3.50.0-01\bin # 前台启动,方便看日志,第一次调试强烈建议这样跑 nexus.exe /run

启动过程会打印一堆 Karaf 容器的日志,等到出现Started Sonatype Nexus OSS字样,说明服务起来了。默认监听8081端口,浏览器访问http://localhost:8081。如果 8081 被占用(比如你机器上跑着别的服务),改etc/nexus-default.properties里的application-port,改完重启。

首次登录的用户名是admin,密码不在文档里,而是生成在:

# 密码文件位置 D:\nexus\sonatype-work\nexus3\admin.password

用记事本打开复制那串随机密码登录,登录后系统会强制你改密码。这个admin.password文件在改完密码后会被自动删除,所以别指望它一直在。

提示:nexus.exe /run是前台运行,关掉窗口服务就停了。生产环境要用nexus.exe /install注册成 Windows 服务,再用net start nexus启动,这样开机自启、后台常驻。

3. 建仓库:把 Maven、npm、Docker 三类制品接进来

3.1 三种仓库类型的区别与选型

Nexus 3 里所有仓库归为三类,理解这三类是配好一切的前提:

  • proxy(代理仓库):代理一个远端公网仓库,第一次拉取时缓存到本地,之后走缓存。适合代理 Maven Central、npmjs、Docker Hub。
  • hosted(宿主仓库):存放团队自己发布的制品,比如你们内部打的 jar、npm 包、Docker 镜像。
  • group(仓库组):把多个 proxy 和 hosted 聚合成一个入口,客户端只配一个地址就能同时拉到公网依赖和内部制品。

典型组合是:建一个maven-centralproxy,建一个maven-releaseshosted,再建一个maven-publicgroup 把前两个加进去。客户端只认maven-public的地址。

3.2 用 REST API 批量建仓库(比点界面可复现)

界面点选容易漏配、难复现,我习惯用 Nexus 自带的 REST API 建仓库。先拿一个能调 API 的账号,用 curl 发请求:

# 建一个 Maven 代理仓库,代理阿里云公共仓库(国内拉取更快) curl -u admin:你的新密码 -X POST "http://localhost:8081/service/rest/v1/repositories/maven/proxy" \ -H "Content-Type: application/json" \ -d '{ "name": "maven-aliyun", "online": true, "storage": { "blobStoreName": "default", "strictContentTypeValidation": true }, "proxy": { "remoteUrl": "https://maven.aliyun.com/repository/public", "contentMaxAge": 1440, "metadataMaxAge": 1440 }, "negativeCache": { "enabled": true, "timeToLive": 1440 }, "httpClient": { "blocked": false, "autoBlock": true }, "maven": { "versionPolicy": "MIXED", "layoutPolicy": "STRICT" } }'

逻辑说明:remoteUrl指向被代理的远端;contentMaxAge是缓存有效期(分钟),1440 表示一天内不再回源;negativeCache开启后,拉不到的包会缓存失败结果,避免每次都去撞墙;versionPolicy设MIXED表示 release 和 snapshot 都代理。参数里最容易踩的是blobStoreName,必须填一个已存在的 blob store,默认就是default,如果你建过自定义存储要对应改。

建 hosted 仓库同理,把 URL 换成/service/rest/v1/repositories/maven/hosted,body 里去掉proxy段,加上"writePolicy": "ALLOW_ONCE"(release 仓库建议设成不允许重复覆盖,防止版本被偷偷改掉)。

3.3 客户端侧怎么指向 Nexus

Maven 项目在settings.xml里配 mirror,把所有请求导到 group 仓库:

<mirrors> <mirror> <id>nexus</id> <mirrorOf>*</mirrorOf> <url>http://内网IP:8081/repository/maven-public/</url> </mirror> </mirrors>

mirrorOf用*表示拦截所有仓库请求。发布制品时在pom.xml的distributionManagement里指向maven-releases或maven-snapshots的地址,并在settings.xml的<servers>里配好 Nexus 账号密码。npm 侧则是npm config set registry http://内网IP:8081/repository/npm-group/,发布时用npm publish --registry http://内网IP:8081/repository/npm-hosted/。

4. 上传制品与版本区分:npm 包和 Maven 包怎么进 Nexus

4.1 npm 包上传前必须先想清楚版本策略

热搜里那个「npm 怎么将组件上传 nexus repository 区分版本,是先打包还是先 npm init」问到了点子上。答案是:先确定版本号,再打包,最后 publish,顺序不能乱。Nexus 的 npm hosted 仓库默认不允许同版本覆盖,一旦你npm publish了一个1.0.0,再想传同名同版本会被拒。所以版本号必须在package.json里定死,而不是发布时临时改。

# 1. 在组件根目录确认 package.json 的 name 和 version cat package.json | grep -E '"name"|"version"' # 2. 登录 Nexus(npm 9+ 用 login 子命令) npm login --registry=http://内网IP:8081/repository/npm-hosted/ # 3. 发布 npm publish --registry=http://内网IP:8081/repository/npm-hosted/

逻辑说明:npm login会把认证 token 写进.npmrc,后续 publish 自动带上。如果你的包是 scoped 包(@company/xxx),要在package.json里加"publishConfig": {"registry": "http://内网IP:8081/repository/npm-hosted/"},否则默认会往公网发。版本区分靠的是语义化版本号:修 bug 升 patch,加功能升 minor,破坏性变更升 major,Nexus 只认版本字符串,不认你的意图,所以团队要约定好。

4.2 Maven 制品用 deploy 上传

Maven 侧不需要手动传文件,mvn deploy会自动推到distributionManagement配的地址:

# 发布 release 版本,pom 里 version 不带 -SNAPSHOT mvn clean deploy -DskipTests

如果 pom 的 version 是1.2.0-SNAPSHOT,它会推到 snapshots 仓库;是1.2.0则推到 releases 仓库。这里有个血泪经验:release 仓库的 writePolicy 设成ALLOW_ONCE后,一旦推错版本就再也覆盖不了,只能删掉整个版本目录再重推,而删除操作在界面上藏得比较深。所以推 release 前先在本地mvn install验证一遍。

4.3 用 curl 直接上传单个文件做验证

有时候只想快速验证仓库通不通,不想走完整构建,可以直接用 REST API 传一个文件:

# 上传一个 jar 到 hosted 仓库的指定路径 curl -u admin:密码 --upload-file ./demo-1.0.0.jar \ "http://localhost:8081/repository/maven-releases/com/demo/demo/1.0.0/demo-1.0.0.jar"

路径必须符合 Maven 的坐标规范groupId/artifactId/version/文件名,否则客户端按坐标找不到。这个方式适合排查「到底是构建问题还是仓库问题」。

5. 避坑与排查:Nexus 在 Windows 上最容易翻车的 5 个点

5.1 启动报端口被占用或卡在 Starting

现象:nexus.exe /run后日志停在Starting...不动,或直接抛Address already in use。原因通常是 8081 被别的进程占了,或者上一次没退干净残留了 Java 进程。解决:netstat -ano | findstr 8081找到 PID,taskkill /PID xxx /F干掉;或者改etc/nexus-default.properties里的端口。改完记得清sonatype-work/nexus3/log下的旧日志再启动,方便看新日志。

5.2 忘记 admin 密码且 admin.password 已删

现象:改完密码后忘了,admin.password文件也没了,登不进去。原因:Nexus 只在首次启动生成一次初始密码。解决:停服务,删掉sonatype-work/nexus3/db/security下的security.xml(会重置所有用户和权限),重启后重新生成admin.password。注意这会清掉你建的所有账号和角色,生产环境慎用,更稳妥的是提前配好 LDAP 或备份security.xml。

5.3 磁盘被 sonatype-work 撑爆

现象:跑几个月后 C 盘或数据盘满了,Nexus 写入失败。原因:proxy 仓库缓存了大量公网依赖,加上定期任务生成的索引和日志。解决:在Tasks里配置Compact blob store和Cleanup unused components定时任务;把 blob store 指向大容量盘;日志按天切割并限制保留天数。我一般把sonatype-work单独挂一块盘,避免和系统盘抢空间。

5.4 客户端拉包 401 或 403

现象:mvn或npm拉包时报认证失败。原因:settings.xml或.npmrc里的账号密码错了,或者该账号没有对应仓库的 read 权限。解决:先在浏览器用同一账号登录 Nexus 验证密码;再检查账号的 Role 是否包含nx-repository-view-*-*-read。npm 侧还要注意 token 过期,重新npm login即可。

5.5 上传的包在 group 仓库里搜不到

现象:包明明传进了 hosted 仓库,但通过 group 地址拉不到。原因:group 仓库没把该 hosted 加进成员列表,或者 group 的成员顺序导致同名包被前面的 proxy 抢先命中。解决:进 group 仓库配置,确认 hosted 在成员列表里;调整顺序把 hosted 放前面,保证内部包优先于公网同名包。

6. 进阶:把 Nexus 当 Docker 镜像仓库并做容量规划

Nexus 3 从 3.x 早期就支持 Docker 仓库,3.50.0这块已经比较成熟。配 Docker hosted 仓库时,需要额外开一个端口(比如 8082)专门给 Docker 用,因为 Docker 协议和 HTTP 仓库协议不共用端口。在etc/nexus-default.properties里加application-port-ssl或直接用docker类型的 connector 配 8082,然后在仓库设置里勾选HTTPconnector 指向 8082。客户端daemon.json里配insecure-registries指向内网IP:8082,之后docker push就能推到 Nexus。

容量规划上,我踩过的最大坑是没给 blob store 留够空间。一个中等团队,proxy 缓存加内部镜像,半年涨到几百 GB 很常见。我的习惯是:blob store 单独一块盘,初始留 500GB 起步;配一个每周执行的Cleanup unused components任务,把 90 天没被拉取过的缓存清掉;再配一个Compact blob store任务回收删除后的空间。这两个任务不配,磁盘只会单向增长。

验证 Nexus 是否健康,我一般看三个指标:Tasks里最近一次清理任务是否成功、System页面的 blob store 使用率、以及随便挑一个内部包用mvn dependency:get或npm view能不能秒拉。这三个都正常,基本就稳了。

说个我自己的教训:早期图省事,把sonatype-work和程序目录放一起,结果一次升级覆盖了整个目录,缓存全丢,团队当天构建全挂。从那以后我养成习惯,升级前先robocopy备份sonatype-work,程序目录随便换,数据目录绝不动。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进