使用 Maven 或 Gradle 等軟體建構工具 (build tool) 常常會需要使用 Maven 套件倉儲 (artifacts repository) 來作為套件存放的地方。過去山姆鍋習慣使用 < a href="http://www.sonatype.org/nexus/" target="_blank" rel="noopener">Nexus Repository Manager 來作為這樣的套件倉儲服務器, Artifactory 雖然沒用過,看起來也很不錯。本來不加思索打算按照習慣用 Nexus 安裝個套件倉儲,或者使用 Artifactory 看看也很新鮮,但突發奇想:可不可以使用 Amazon S3 來作為 Maven repository?有什麼問題跟限制?

說是突發奇想也不全然是事實,畢竟「影化身科技」的發展策略之一就是盡量採用雲端服務而不自行管理服務器。基於這個方向便開始 Google 相關的文章,看看有沒有可能完成這個挑戰。

使用 S3 作為套件倉儲的好處

Amazon S3 作為儲存服務,提供下列好處:

  • 可靠性高:資料在同一個區域,多個資料中心存放。
  • 可用性高:不會因為單一服務器或資料中心故障導致無法使用。
  • 整合 IAM:可以限制可以存取的機器或用戶。

支援 S3 作為套件倉儲的方法

本來以為會很麻煩,想不到 Google 一下就發現已經有人提出 < a href="http://blog.brickcitylabs.com/2012/02/hosting-maven-repository-on-amazons-s3.html" target="_blank" rel="noopener">解決方法。所提的方法適用以 Maven 作為建構工具,目前還沒有發現使用 Gradle 的做法。

首先在您個人的 Maven 設定檔 (通常位於~/.m2/settings.xml) 加入兩個 & quot;<server/>" 片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>maven-s3-release-repo</id>
<username>ACCESS_KEY_ID</username>
<passphrase>SECRET_ACCESS_KEY</passphrase>
</server>
<server>
<id>maven-s3-snapshot-repo</id>
<username>ACCESS_KEY_ID</username>
<passphrase>SECRET_ACCESS_KEY</passphrase>
</server>
</servers>
</settings>

其中,ACCESS_KEY_ID/SECRET_ACCESS_KEY 就是從 Amazon 控制台產生的 security credentials(安全憑證)。

針對要發佈到 Amazon S3 的專案,修改其 pom.xml。主要有兩個部分,第一部分是在 < build > 元素中加入 org.springframework.build.aws.maven 這個擴充功能,讓 Maven 知道符合發佈到 S3。

1
2
3
4
5
6
7
8
9
<build>
<extensions>
<extension>
<groupId>org.springframework.build.aws</groupId>
<artifactId>org.springframework.build.aws.maven</artifactId>
<version>3.0.0.RELEASE</version>
</extension>
</extensions>
</build>

再來就是加入幾個套件倉儲位置的宣告:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<repositories>
<repository>
<id>maven-s3-release-repo</id>
<name>S3 Release Repository</name>
<url>s3://S3_BUCKET_NAME/release</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>maven-s3-snapshot-repo</id>
<name>S3 Snapshot Repository</name>
<url>s3://S3_BUCKET_NAME/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>maven-s3-release-repo</id>
<name>S3 Release Repository</name>
<url>s3://S3_BUCKET_NAME/release</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>maven-s3-snapshot-repo</id>
<name>S3 Snapshot Repository</name>
<url>s3://S3_BUCKET_NAME/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>

<distributionManagement>
<repository>
<id>maven-s3-release-repo</id>
<name>S3 Release Repository</name>
<url>s3://S3_BUCKET_NAME/release</url>
</repository>
<snapshotRepository>
<id>maven-s3-snapshot-repo</id>
<name>S3 Snapshot Repository</name>
<url>s3://S3_BUCKET_NAME/snapshot</url>
</snapshotRepository>
</distributionManagement>

S3_BUCKET_NAME 自然要跟您建立的 S3 bucket 名稱相對應。

最後 < a href="https://plus.google.com/109306194635997164777" target="_blank" rel="noopener">原文作者 也提供了實際範例,放在 GitHub 上供人參考: https://github.com/mberwanger/s3-maven-example。 Kudos to Mr. Berwanger.

小結

利用 Amazon S3 作為 Maven 套件倉儲便可以運用 S3 所俱備的高可用、高擴充的儲存能力,再加上 CloudFront CDN 服務,不管在哪個地方都可以方便開發與部署。如果讓建構服務器 (build server) 跟 S3 位於同一個 Availability zone 還可以免除頻寬的費用。