本文档用于搭建公司内部 Maven 私有仓库,目标是统一管理公司私有 jar、第三方离线 jar 和 Maven Central 代理缓存,避免每次新环境都手工复制 jar。

维护: Nexus Repository、Docker 镜像、Maven 配置和权限模型可能随版本变化。本文最后核对日期为 2026-05-26,生产落地前应再核对 Sonatype Nexus Repository 和 Apache Maven 官方文档。

先看结论

推荐使用 Sonatype Nexus Repository Community Edition。旧资料中常见的 “Nexus Repository OSS” 可以理解为同类免费版本口径,实际落地时以当前 Sonatype 官方命名和授权说明为准。

  • maven-public:所有开发机和 CI 只配置这一个下载入口。
  • maven-releases:发布公司内部正式版本 jar。
  • maven-snapshots:发布公司内部快照版本 jar。
  • maven-thirdparty:存放供应商、历史系统或无法从 Central 获取的第三方 jar。
  • maven-central:代理 Maven Central,减少重复下载并提升稳定性。

最终效果:

1
2
3
4
5
6
7
开发机 / CI
-> Maven settings.xml
-> https://nexus.example.com/repository/maven-public/
├── maven-releases
├── maven-snapshots
├── maven-thirdparty
└── maven-central proxy

不推荐继续复制 jar

手工复制 jar 的问题:

  • 新环境容易漏 jar。
  • jar 版本来源不清楚。
  • 本地 ~/.m2/repository 变成隐式依赖,CI 不可复现。
  • 多人环境里同一个 jar 可能有不同内容。
  • 无法统一权限、审计和备份。

正确做法是把 jar 发布到 Maven 私有仓库,让项目通过正常的 Maven 坐标依赖它。

1
2
3
4
5
<dependency>
<groupId>com.company.thirdparty</groupId>
<artifactId>vendor-sdk</artifactId>
<version>1.0.0</version>
</dependency>

仓库规划

建议仓库命名:

仓库 类型 用途
maven-central proxy 代理 Maven Central,推荐使用 https://repo.maven.apache.org/maven2/
maven-releases hosted 公司内部正式版本
maven-snapshots hosted 公司内部 *-SNAPSHOT 版本
maven-thirdparty hosted 无法从公共仓库获取的第三方 jar
maven-public group 聚合所有 Maven 仓库,对开发机和 CI 暴露

maven-public 成员顺序建议:

1
2
3
4
maven-releases
maven-snapshots
maven-thirdparty
maven-central

如果公司内部包名和第三方包名有冲突,优先通过清晰的 groupId 规避,不要把不同来源的 jar 发布成同一个坐标。

部署 Nexus

下面用 Docker Compose 部署单节点 Nexus。生产环境建议放在内网服务器上,并通过 Nginx / 网关提供 HTTPS。

创建目录:

1
2
sudo mkdir -p /opt/nexus
cd /opt/nexus

创建 docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
services:
nexus:
image: sonatype/nexus3:latest
container_name: nexus
restart: unless-stopped
ports:
- "8081:8081"
volumes:
- nexus-data:/nexus-data
environment:
INSTALL4J_ADD_VM_PARAMS: "-Xms2g -Xmx2g -XX:MaxDirectMemorySize=2g"

volumes:
nexus-data:

说明:latest 适合快速验证;生产环境建议固定明确版本 tag,并在升级前阅读 Sonatype release notes。

启动:

1
2
docker compose up -d
docker compose logs -f nexus

访问:

1
http://服务器IP:8081/

首次登录:

1
docker exec -it nexus cat /nexus-data/admin.password

用户名是:

1
admin

登录后按向导修改管理员密码。

基础安全配置

第一次初始化后,先做这些事:

  1. 修改 admin 密码。
  2. 创建独立用户,不要让开发人员共用 admin
  3. 只给普通开发和 CI 读 maven-public 的权限。
  4. 只给发布账号写 maven-releasesmaven-snapshotsmaven-thirdparty
  5. 外部访问必须走 HTTPS,不要在公网裸露 8081
  6. 定期备份 Nexus 数据卷。

如果只在内网使用,可以关闭 anonymous write;是否允许 anonymous read 取决于公司安全要求。更稳妥的默认策略是:所有访问都需要账号,CI 使用专用只读账号。

创建 Maven 仓库

Nexus 默认通常已经包含:

  • maven-central
  • maven-releases
  • maven-snapshots
  • maven-public

如果没有 maven-thirdparty,手动创建:

1
Repository -> Create repository -> maven2 (hosted)

建议配置:

1
2
3
4
Name: maven-thirdparty
Version policy: Release
Layout policy: Strict
Deployment policy: Disable redeploy

然后编辑 maven-public group,把 maven-thirdparty 加入 members。

Maven settings.xml

Maven 的用户级配置文件在:

1
~/.m2/settings.xml

Windows 常见路径:

1
C:\Users\<用户名>\.m2\settings.xml

开发机和 CI 推荐统一使用 maven-public 作为 mirror:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>company-maven-public</id>
<name>Company Maven Public</name>
<url>https://nexus.example.com/repository/maven-public/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>

<servers>
<server>
<id>company-maven-releases</id>
<username>${env.MAVEN_REPO_USER}</username>
<password>${env.MAVEN_REPO_PASSWORD}</password>
</server>
<server>
<id>company-maven-snapshots</id>
<username>${env.MAVEN_REPO_USER}</username>
<password>${env.MAVEN_REPO_PASSWORD}</password>
</server>
<server>
<id>company-maven-thirdparty</id>
<username>${env.MAVEN_REPO_USER}</username>
<password>${env.MAVEN_REPO_PASSWORD}</password>
</server>
</servers>
</settings>

说明:

  • <mirrors> 控制下载依赖走哪里。
  • <servers> 保存上传仓库的认证信息。
  • server.id 必须和上传命令里的 repositoryId,或项目 pom.xmldistributionManagement.repository.id 一致。
  • 不建议把明文密码写进项目仓库。开发机可用环境变量,CI 用密钥变量。

上传已有第三方 jar

适合场景:

  • 厂商给了一个 vendor-sdk.jar
  • 老系统只有 jar,没有 Maven 坐标。
  • 公共仓库没有这个依赖。

先确定坐标。建议使用公司统一命名空间,避免污染真实开源坐标:

1
2
3
4
groupId: com.company.thirdparty
artifactId: vendor-sdk
version: 1.0.0
packaging: jar

上传到 maven-thirdparty

1
2
3
4
5
6
7
8
mvn deploy:deploy-file \
-DgroupId=com.company.thirdparty \
-DartifactId=vendor-sdk \
-Dversion=1.0.0 \
-Dpackaging=jar \
-Dfile=./vendor-sdk-1.0.0.jar \
-DrepositoryId=company-maven-thirdparty \
-Durl=https://nexus.example.com/repository/maven-thirdparty/

如果厂商同时提供 POM:

1
2
3
4
5
mvn deploy:deploy-file \
-DpomFile=./vendor-sdk-1.0.0.pom \
-Dfile=./vendor-sdk-1.0.0.jar \
-DrepositoryId=company-maven-thirdparty \
-Durl=https://nexus.example.com/repository/maven-thirdparty/

上传成功后,项目中正常声明依赖:

1
2
3
4
5
<dependency>
<groupId>com.company.thirdparty</groupId>
<artifactId>vendor-sdk</artifactId>
<version>1.0.0</version>
</dependency>

验证:

1
2
mvn dependency:get \
-Dartifact=com.company.thirdparty:vendor-sdk:1.0.0

发布公司内部 jar

如果是公司自己维护的模块,推荐在项目 pom.xml 中配置 distributionManagement

1
2
3
4
5
6
7
8
9
10
11
12
<distributionManagement>
<repository>
<id>company-maven-releases</id>
<name>Company Maven Releases</name>
<url>https://nexus.example.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>company-maven-snapshots</id>
<name>Company Maven Snapshots</name>
<url>https://nexus.example.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>

发布:

1
mvn clean deploy

规则:

  • 正式版本,例如 1.2.0,进入 maven-releases
  • 快照版本,例如 1.2.1-SNAPSHOT,进入 maven-snapshots
  • release 版本不要重复覆盖。需要修复就发布新版本。

新环境接入流程

以后新开发机或新 CI 环境只需要:

  1. 安装 JDK 和 Maven。
  2. 创建 ~/.m2/settings.xml
  3. 配置 MAVEN_REPO_USERMAVEN_REPO_PASSWORD
  4. 执行:
1
mvn -U clean test

如果项目依赖已经全部进入 Nexus,就不需要再复制任何 jar。

常见问题

依赖还是从 Maven Central 下载

检查:

  • settings.xml 是否在正确位置。
  • <mirrorOf>*</mirrorOf> 是否写对。
  • 当前 Maven 是否使用了另一个 settings:
1
mvn help:effective-settings

401 Unauthorized

检查:

  • settings.xmlserver.id 是否和 repositoryIddistributionManagement.repository.id 一致。
  • 环境变量是否存在:
1
2
echo "$MAVEN_REPO_USER"
echo "$MAVEN_REPO_PASSWORD"
  • Nexus 用户是否有对应仓库的写权限。

404 Not Found

检查:

  • 上传 URL 是否是 hosted 仓库,不要上传到 group 仓库。
  • maven-thirdparty 是否已加入 maven-public
  • groupIdartifactIdversion 是否和项目依赖一致。

release 版本上传失败

常见原因是 Deployment policy 禁止 redeploy。正式版本不应覆盖,这是正确行为。

处理方式:

  • 如果是误传,管理员删除错误组件后重新上传。
  • 如果是正常修复,发布新版本,例如 1.0.1

snapshot 依赖没有更新

执行:

1
mvn -U clean test

同时检查 maven-snapshots 的版本策略是否是 Snapshot

运维建议

  • Nexus 数据卷必须纳入备份。
  • 每次升级前先看 Sonatype release notes。
  • 对外只暴露 HTTPS 入口。
  • 不要让所有人都有 deploy 权限。
  • 私有 jar 必须有清晰坐标和来源记录。
  • 禁止把同一个坐标上传不同内容。
  • CI 使用只读账号下载依赖,发布流水线使用单独 deploy 账号。
  • 定期清理无用 snapshot,避免磁盘无限增长。

参考

迭代记录

  • 2026-05-26:初始化 Maven 私有仓库搭建指南,基于 Nexus Repository Community Edition 方案整理仓库规划、Docker Compose 部署、settings.xml、第三方 jar 上传、内部 jar 发布和新环境接入流程。