Maven 依赖下载慢是很多 Java 团队的老大难问题。项目一旦上规模,依赖动辄几百个,全靠开发者本机直连中央仓库下载,既浪费带宽,又难以做统一的版本管控。解决办法就是架设一个 Maven 私服:所有依赖请求先走内网私服,私服没有的再转发到中央仓库并缓存下来,第二次构建时直接命中本地缓存,速度可以快一个数量级。本文以 Sonatype Nexus3 为例,介绍如何用 Docker 在十分钟内搭好一套可用的私服。

一、用 Docker 部署 Nexus3
Nexus3 官方提供了 Docker 镜像,部署非常简单。首先准备一个目录用于持久化数据,Nexus 的仓库数据、配置、日志都存放在容器的 /nexus-data 目录下,如果不挂载出来,容器删掉数据就没了。
创建目录并调整权限,Nexus 容器内部是以 nexus 用户(uid 200)运行的,宿主机目录必须有写权限,否则容器会启动失败:
mkdir -p /data/nexus-data chown -R 200:200 /data/nexus-data
然后启动容器。Nexus3 需要的内存建议不低于 2G,如果宿主机内存紧张,可以通过环境变量调整 JVM 参数:
docker run -d \ --name nexus3 \ --restart=always \ -p 8081:8081 \ -v /data/nexus-data:/nexus-data \ -e INSTALL4J_ADD_VM_PARAMS="-Xms1g -Xmx2g -XX:MaxDirectMemorySize=2g" \ sonatype/nexus3
容器启动后需要等待一两分钟,Nexus 初始化比较慢。用 docker logs -f nexus3 观察日志,看到 Started Sonatype Nexus OSS 字样说明启动完成。此时访问 http://服务器IP:8081 即可打开管理界面。
首次登录需要管理员密码,密码存放在挂载目录下:/data/nexus-data/admin.password。用 cat 命令查看内容,以 admin 用户名登录,登录后系统会引导你修改密码并创建匿名账号。建议开启匿名访问,这样开发人员在拉取依赖时不需要配置认证,只有发布构件时才需要账号。
二、创建并理解仓库结构
Nexus3 默认已经创建了 maven-public 这个 group 仓库,它聚合了 maven-central(代理中央仓库)、maven-releases(宿主发布仓库)和 maven-snapshots(快照仓库)。对大多数团队来说,直接使用默认结构就够了,不需要额外创建仓库。
不过有几点值得检查和调整。第一是代理仓库的地址,默认的中央仓库地址在国外,可以改成阿里云镜像来加速。进入后台的配置页面,选择 Repository > Repositories > maven-central,把 Remote storage 改成:
https://maven.aliyun.com/repository/public
第二是宿主仓库的部署策略。maven-releases 默认禁止重复部署同一版本,这是合理的规范,可以防止已发布的版本被偷偷覆盖。如果团队在调试阶段需要反复发布,可以在 Deployment policy 中临时改为 Allow redeploy,但正式环境强烈建议保持 Disable redeploy。
第三,如果使用默认的 maven-public 时出现快照依赖拉不到的问题,需要检查 maven-public 的 Member repositories 里是否包含了 maven-snapshots。有些旧版本默认没勾选,手动加上即可。
三、配置 settings.xml 拉取依赖
私服搭好后,客户端只需要修改 Maven 的 settings.xml(一般在 ~/.m2/settings.xml)。核心配置是把所有仓库请求都镜像到私服的 group 仓库地址:
<settings>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://192.168.1.100:8081/repository/maven-public/</url>
</mirror>
</mirrors>
<servers>
<server>
<id>nexus</id>
<username>admin</username>
<password>你的密码</password>
</server>
</servers>
</settings>
</settings>
这里有两个细节要注意。mirrorOf 写成 * 表示拦截所有仓库请求,包括项目 pom 里自定义的仓库;如果只想代理中央仓库,可以写 central。server 的 id 必须和 mirror 的 id 一致,Maven 靠这个 id 匹配认证信息。
另一个常见的坑是 HTTPS 校验问题。Maven 3.8.x 开始默认阻止外部 HTTP 仓库,如果私服用的是 HTTP 协议,可能会报 Blocked mirror for repositories 之类的错误。解决办法有两个:要么给 Nexus 配置 HTTPS(生产环境推荐),要么把 mirror 地址的协议处理一下,或者降级 Maven 版本。内网环境下最省事的做法是在 Nginx 层做 HTTPS 反向代理,同时保留后端 HTTP。
四、发布自己的构件到私服
团队内部的项目往往需要互相依赖,这时候就要把 jar 包发布到私服的宿主仓库。在项目的 pom.xml 中配置分发地址:
<distributionManagement>
<repository>
<id>nexus-releases</id>
<url>http://192.168.1.100:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<url>http://192.168.1.100:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
同样地,settings.xml 中要有 id 为 nexus-releases 和 nexus-snapshots 的 server 配置,否则执行 mvn deploy 时会返回 401 未授权。配置好后运行:
mvn clean deploy
版本号带 -SNAPSHOT 后缀的会自动发布到 maven-snapshots,正式版本发布到 maven-releases,Nexus 会根据版本号自动路由,不需要手动指定。
对于第三方提供的、中央仓库没有的 jar 包(比如某些商业驱动),可以在 Nexus 管理界面上传:进入 maven-releases 仓库页面,点击 Upload,选择 pom 打包方式并填写 GAV 坐标即可。上传后的构件立刻可以通过 group 仓库被所有开发人员引用。
五、日常维护建议
私服用起来之后,磁盘会持续增长,因为所有下载过的依赖都会被缓存。可以创建定时任务定期清理没人在用的构件:在后台 Server administration 中选择 Task,新建一个 Admin - Cleanup repositories 任务,设定执行周期。注意不要误删 releases 仓库中还在被项目引用的版本。
备份方面,由于所有数据都在 /nexus-data 目录,最简单的方案就是定时 rsync 这个目录,或者在停机窗口做完整备份。有条件的可以借助 Nexus 的 blob store 机制,把存储指向独立磁盘,方便扩容和管理。另外建议给私服加上 HTTPS 和统一的账号权限管理,CI 机器发布构件时使用专门的部署账号,避免所有人共享 admin 密码。
整体来看,用 Docker 搭建 Nexus3 私服的成本很低,一次部署长期受益。它不仅加速了依赖下载,还是团队内部构件分发的唯一入口,配合 CI/CD 流水线使用效果更佳。
Docker搭建Maven私服Nexus3部署Maven仓库配置修改时间:2026-09-13 15:50:54