史上最详细的 Maven 私服搭建与使用指南

1,775 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Maven 私服搭建

私服是架设在局域网的一种特殊的远程仓库, 目的是代理远程仓库及部署第三方构件. 有了私服之后, 当 Maven 需要下载构件时, 直接请求私服, 私服上存在则下载到本地仓库;否则, 私服请求外部的远程仓库, 将构件下载到私服, 再提供给本地仓库下载.

Maven 获取依赖的流程 :

  • 首先访问本地仓库
  • 如果本地仓库找不到, 去私服仓库中查找.
  • 如果没有私服仓库, 或者私服仓库找不到.
  • 则访问中心仓库 Maven Respository. mvnrepository.com

使用 docker 搭建

  • 下载 Nexus 镜像 : docker pull sonatype/nexus3
  • 启动 Nexus 容器 : docker run -d -p 9991:8081 --name nexus -v /var/opt/nexus/nexus-data:/nexus-data --restart=always sonatype/nexus3 将容器内部的 /var/nexus-data 目录挂载到当前主机的 /var/opt/nexus/nexus-data 目录.
  • 启动容器后, 等待片刻, 访问 http://IP:9991/ , 可以看到 Nexus 管理后台就表示私服安装完成了.

① 遇到的坑:

启动 Nexus 容器总是启动不起来. 然后重新启动一下, 这次不总是重启 : docker run -d -p 9991:8081 --name nexus -v /var/opt/nexus/nexus-data:/nexus-data sonatype/nexus3

发现启动失败. 查看日志 : docker logs -f nexus

 java.io.FileNotFoundException: ../sonatype-work/nexus3/tmp/i4j_ZTDnGON8hezynsMX2ZCYAVDtQog=.lock (No such file or directory)
 
 java.io.FileNotFoundException: /nexus-data/karaf.pid (Permission denied)
 
 java.lang.RuntimeException: /nexus-data/log/karaf.log (No such file or directory)
 
 Caused by: java.io.FileNotFoundException: /nexus-data/log/karaf.log (No such file or directory)

启动 nexus 时, 为容器挂在了数据卷 -v /var/opt/nexus/nexus-data:/nexus-data, 但是并没有对数据卷目录进行授权, 容器没有权限操作宿主机文件夹.

修改宿主机 /var/opt/nexus/nexus-data 文件夹权限,这里先授予所有权限. chmod 777 /var/opt/nexus/nexus-data 之后再重启容器即可.

私服配置

私服安装之后, 首先进行登录, 点击页面左上角的 Sign In 按钮, 就会出现和下图一样的提示 :

Nexus 默认登录账号为 admin, 并且密码位于文件 /nexus-data/admin.password 下, 我们只需在本地配置的挂载目录 /var/opt/nexus/nexus-data 下查看该文件即可.

输入默认的账号密码之后成功登录之后, Nexus 就会强制要求修改 admin 的密码 ( 我这里密码使用的 admin ), 并且设置基本访问权限, 完成之后就正式进入了 Nexus 私服后台.

进入私服程序的配置界面, 我们需要对默认配置进行几点调整.

① 修改私服的中央仓库位置

将私服配置里中央仓库的代理仓库路径修改为 阿里云仓库 提供的代理地址:

maven.aliyun.com/repository/… 加速访问依赖.

② 创建 hosted 类型的仓库

类型具体说明
hosted本地存储. 像官方仓库一样提供本地私库功能
proxy提供代理其它仓库的类型
group组类型, 能够组合多个仓库为一个地址提供服务

点击 Create repository :

然后选择类型为 maven2(hosted)

然后输入仓库名称, 并在 Version policy 一栏中选择 Release, 表示这个仓库的存储依赖为正式发布的组件, 然后在 Deployment policy 一栏中选择 Allow redeploy, 允许部署和更新私服上的组件.

最后点击 Create repository, 就可以在仓库列表看到自定义的仓库了.

有了 release 仓库, 我们再按照同样方式操作添加一个 snapshot 仓库, 只需在 Version policy 一栏调整为 Snapshot 即可.

③ 添加角色 (可选)

Nexus 默认只有两种角色:nx-anonymousnx-admin, 前者只有浏览的权限, 后者为管理员权限, 一般情况下, 我们还需要正对开发人员创建个角色.

点击 Create Role, 添加一个 Role ID 为 developer 的自定义角色, 并且只添加自定义仓库的使用权限, 删除操作除外.

④ 添加用户

跟权限类似, 默认的用户只有两种:admin 和 anonymous, 我们同样需要创建属于开发者的用户对象. 、

点击 Create local user, 填入用户名, 密码等必填信息之后, 关联角色, 并保存即可. 我这里创建的用户是 sjy, 密码是 sjy.

用户创建完成之后, 我们就可以用新的用户登录私服, 查看对应权限的内容了.

将本地的 Maven 仓库迁移到 Maven 私服

使用迁移工具 migrate-local-repo-tool.jar 进行迁移 :

下载地址 : 点击下载

在 CMD 中, 使用如下命令进行依赖的迁移 :

java -jar migrate-local-repo-tool.jar -cd "C:/maven/RepMaven" -t "http://IP地址:9991/repository/maven-central/" -u 用户名 -p 密码

参数说明 :

  • -cd 您要迁移的本地目录.
  • -t 目标仓库地址.
  • -u 用户名.
  • -p 密码.
  • 注意 : -cd 后面的目录要用反斜杠 /, 不论是 linux 上还是 windows 上

测试使用 :

在 e:/rep 目录下有如下两个依赖, 现将其上传到 Maven 私服.

使用命令上传 :

没报错, 则表示上传成功, 输出的日志中 Skipped Deployments 列出了上传成功的依赖.

使用 Maven 私服下载依赖

有了私服和连接的账号, 我们就需要在本地 Maven 配置文件 setting.xml 进行关联.

① 设置 server 账户信息

servers节点中, 配置 server. 用于连接 Maven 私服时进行认证.

  • id 可以自己命名 后面需要与项目中保持一致.
  • username 可以是 admin, 也可以是自己新创建的用户, 密码同上.
<servers>
  <!-- 下载时的认证 -->
  <server>
    <id>sjy</id>
    <username>sjy</username>
    <password>sjy</password>
  </server>
</servers>

② 设置私服仓库地址

以下设置都是在 maven 的 conf / setting.xml 中进行配置.

设置下载依赖的地址, 在mirrors标签下添加 如下内容 :

<mirrors>
  <!-- 用搭建好的私服的地址 -->
  <mirror>
    <id>central</id>
    <mirrorOf>*</mirrorOf>
    <name>Central Repository</name>
    <!-- 私服里中央仓库的地址 -->
    <url>http://106.13.227.74:9991/repository/maven-central/</url>
  </mirror>
  <!-- 把阿里云的注释掉 -->
  <!-- <mirror>
         <id>nexus-aliyun</id>
         <mirrorOf>central</mirrorOf>
         <name>Nexus aliyun</name>
         <url>http://maven.aliyun.com/nexus/content/groups/public</url>
     </mirror> -->
</mirrors>

 ③ 测试下载

创建 Maven 工程, 引入一个本地仓库中没有的依赖, 如下 :

<dependencies>
  <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.20</version>
  </dependency>
</dependencies>

Maven 工程不用进行其他操作.

右键 -> maven -> reimport

此时私服是空的, 啥依赖都没有, 可以看到, 已经通过私服仓库下载啦.

打开私服管理界面, 可以看到, 已经下载到私服了.

发布本地项目到 Maven 私服

① maven 配置 :

首先在 Maven 的 setting.xml 中配置登录信息. 因为 Nexus 的仓库对于匿名用户是只读的, 为了能够部署构件, 还需要配置认证信息.

<servers>
  <!-- 下载认证 -->
  <server>
    <id>sjy</id>
    <username>sjy</username>
    <password>sjy</password>
  </server>
  <!-- 部署认证 -->
  <server>
    <id>private-rep-release</id>  <!-- id 和下面 profiles 中的配置一致-->
    <username>sjy</username>
    <password>sjy</password>
  </server>
  <!-- 部署认证 -->
  <server>
    <id>private-rep-snapshot</id>
    <username>sjy</username>
    <password>sjy</password>
  </server>
</servers>

在 profiles 标签下添加如下内容 :

<profiles>
  <profile>
    <id>dev</id>
    <repositories>
      <repository>
        <id>private-rep-release</id>
        <url>http://106.13.227.74:9991/repository/private-rep-release/</url>
      </repository>
      <repository>
        <id>private-rep-snapshot</id>
        <url>http://106.13.227.74:9991/repository/private-rep-snapshot/</url>
      </repository>
    </repositories>
  </profile>

  ...

</profiles>

<activeProfiles>
  <activeProfile>dev</activeProfile>
</activeProfiles>

② 项目配置 :

在项目的 pom.xml 文件中进行如下配置 :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>it</groupId>
  <artifactId>com</artifactId>
  <version>1.0-RELEASE</version>

  <dependencies>
    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.16</version>
    </dependency>
  </dependencies>


  <!--注意限定版本一定要和上面 <version> 标签保持一致.所以此处为RELEASE,所以上传的对应仓库的存储类型为RELEASE-->
  <!-- 指定仓库名称 -->
  <distributionManagement>
    <repository>
      <!--id与 maven settings.xml 中的 id 文件保持一致-->
      <id>private-rep-release</id>
      <!--对应的私服仓库地址-->
      <url>http://106.13.227.74:9991/repository/private-rep-release/</url>
    </repository>
  </distributionManagement>

  <build>
    <plugins>
      <!--发布代码Jar插件-->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-deploy-plugin</artifactId>
        <version>2.7</version>
      </plugin>
      <!--发布源码插件-->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>2.2.1</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

然后在 IDEA 中打开 maven 菜单, 双击 deploy 按钮.

即可完成发布 :

遇到的坑 :

  • 点击 deploy 发布时, 发布失败, 错误信息为 : Return code is: 401, ReasonPhrase:Unauthorized.
  • 错误原因:未添加到检出私服的的认证. 也就是 setting.xml 中的 servers 标签下少上面的配置.

拉取发布的项目

有时候我们发布的项目有可能是通用的工具类包, 需要在其他项目中使用, 使用如下方式拉取.

找到依赖 :

在 pom 中引入 :

<dependency>
  <groupId>it</groupId>
  <artifactId>com</artifactId>
  <version>1.0-RELEASE</version>
</dependency>
<repository>
  <id>private-rep-release</id>
  <url>http://IP地址:9991/repository/private-rep-release/</url>
</repository>