前言

Q: 为啥不用nexus

A: 内存不够

Q: 为啥不加内存

A: 时代的局限 历史的遗留 无奈的抉择 必要的牺牲 伟大的探索 曲折的前进 ……

总之,你现在需要用比运行nexus更加轻量级的方式来实现一个私有的maven仓库

于是你把目光投向了nginx

开始

开始之前

要想让maven正确地获取到依赖项,我们首先需要明确一个典型的依赖项在maven仓库中存储的目录结构

这里我们以若依框架pom.xml作为依赖项为例。当我们想要在仓库上存储ruoyi的依赖项的时候,文件结构如下

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
31
32
33
❯ tree /var/www/maven-repo
/var/www/maven-repo
├── com
│   └── ruoyi
│   ├── ruoyi
│   │   ├── 3.6.4
│   │   │   ├── ruoyi-3.6.4.pom
│   │   │   ├── ruoyi-3.6.4.pom.md5
│   │   │   └── ruoyi-3.6.4.pom.sha1
│   │   ├── maven-metadata.xml
│   │   ├── maven-metadata.xml.md5
│   │   └── maven-metadata.xml.sha1
│   ├── ruoyi-api
│   │   ├── 3.6.4
│   │   │   ├── ruoyi-api-3.6.4.pom
│   │   │   ├── ruoyi-api-3.6.4.pom.md5
│   │   │   └── ruoyi-api-3.6.4.pom.sha1
│   │   ├── maven-metadata.xml
│   │   ├── maven-metadata.xml.md5
│   │   └── maven-metadata.xml.sha1
│   ├── ruoyi-api-system
│   │   ├── 3.6.4
│   │   │   ├── ruoyi-api-system-3.6.4.jar
│   │   │   ├── ruoyi-api-system-3.6.4.jar.md5
│   │   │   ├── ruoyi-api-system-3.6.4.jar.sha1
│   │   │   ├── ruoyi-api-system-3.6.4.pom
│   │   │   ├── ruoyi-api-system-3.6.4.pom.md5
│   │   │   └── ruoyi-api-system-3.6.4.pom.sha1
│   │   ├── maven-metadata.xml
│   │   ├── maven-metadata.xml.md5
│   │   └── maven-metadata.xml.sha1
│ └── # 当然这里还有很多,不一一列举了
└── index.html

对于一个包名为org.examlple.my-artifact:1.0.0的依赖项而言,其存储的位置为

<repository_root>/org/example/my-artifact/1.0.0/

每个存放依赖项的目录下的 maven-metadata.xml 文件用于存储该目录中与 Maven 项目相关的元数据信息。以org.examlple.my-artifact为例,该文件的内容可能是这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<metadata>
<groupId>com.example</groupId>
<artifactId>my-artifact</artifactId>
<versioning>
<latest>1.2.0</latest>
<release>1.2.0</release>
<versions>
<version>1.0.0</version>
<version>1.1.0</version>
<version>1.2.0</version>
</versions>
<lastUpdated>20230708120000</lastUpdated>
<snapshot>
<timestamp>20230708.120000</timestamp>
<buildNumber>1</buildNumber>
</snapshot>
</versioning>
</metadata>

对于单个的打包为**.jar**依赖项而言,存储的文件有

  • xxxx.jar
  • xxxx.pom
  • xxxx.jar.md5
  • xxxx.jar.sha1
  • xxxx.pom.md5
  • xxxx.pom.sha1

其中真正有作用的是xxxx.jar以及xxxx.pom文件

.jar文件为该依赖项的代码实现,.pom文件其实就是该依赖项在项目中的pom.xml文件,如ruoyi-api-system子模块

对于多个jar依赖的父项目而言,没有代码的情况下,只会有xxxx.pom文件,该文件对应其项目中的pom.xml,如目录树中的ruoyi等父项目模块

配置nginx

nginx在其中需要扮演的角色为静态文件服务器

所以只需要配置一个路径作为仓库根目录就行了

1
2
3
4
5
location /repository {
alias /var/www/maven-repo;
autoindex on;
try_files $uri $uri/ =404;
}

当然你需要确保nginx有权读取这个目录

1
2
sudo chown -R www-data:www-data /var/www/maven-repo
sudo chmod -R 777 /var/www/maven-repo # 这条命令请你自己灵活修改

然后你就可以在配置的网址看到类似下面的页面了

autoindex

构建工件并推送

解决了仓库,就需要解决工件文件的问题了

手动构建上传显然太没效率,这里我们提出一个解决方案:使用maven的wagon-ssh插件进行部署上传

配置settings.xml

在maven==使用的settings.xml==中的<servers>标签中添加<server>节点,在里面填写服务器识别id(自定义,后面要用),登录nginx远程服务器的用户名和私钥[1]文件位置

1
2
3
4
5
6
7
8
9
10
<server>
<!-- 自定义的id -->
<id>your-server-id</id>
<!-- 部署nginx的服务器登录用户名 -->
<username>your-username</username>
<!-- 私钥文件路径 -->
<privateKey>C:\\Users\\mahiro\\.ssh\\id_rsa</privateKey>
<!-- 如果你的私钥有密码的话,就要写下面这个标签 -->
<!-- <passphrase>your-key-passphrase</passphrase> -->
</server>

然后在<profiles>标签中添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<profile>
<id>your-profile-id</id>
<repositories>
<repository>
<id>your-repo-id</id>
<url>your-repo-url</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>

并在<activeProfiles>标签(没有就在<settings>标签内新建一个)内添加该<profile>标签

1
<activeProfile>your-profile-id</activeProfile>

profile activated in idea

配置pom.xml

在你需要上传到nginx上的工件的pom.xml中添加下列内容[2]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<distributionManagement>
<repository>
<id>your-server-id</id>
<url>scp://your-server-url/var/www/maven-repo</url>
</repository>
</distributionManagement>

<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>3.3.4</version> <!-- 使用合适的版本 -->
</extension>
</extensions>
</build>

然后执行mvn deploy,就可以将构建好的工件推送到你的远程服务器上了

使用

如果你为maven配置了镜像(比如阿里云maven),则需要在镜像中排除掉自定义的仓库才可以使用到你的自定义仓库

1
2
3
4
5
6
 <mirror>
<id>aliyunmaven</id>
<mirrorOf>*,!your-repo-id</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>

直接在pom.xml中引用即可,镜像里面找不到的工件会去自定义仓库里找

1
2
3
4
5
6
7
<dependencies>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-core</artifactId>
<version>3.6.4</version>
</dependency>
</dependencies>

构建

1
mvn compile

仓库使用鉴权

下次写



  1. 私钥的形式有特殊要求,详情见本脚注

    本文中使用的maven ssh插件wagon-ssh版本号为3.3.4,经过实测,该版本号支持开头如下的rsa算法的私钥:

    1
    -----BEGIN RSA PRIVATE KEY-----

    但是不支持

    1
    -----BEGIN OPENSSH PRIVATE KEY-----

    开头的私钥

    你可以使用

    1
    ssh-keygen -m PEM -t rsa -b 4096 -C "focnal@example.com"

    来生成上面提到的这种受支持的rsa密钥对 ↩︎

  2. 你可以在父工件的pom.xml中填入,该工件的所有子工件都会应用该设置 ↩︎