Sonatype Nexusのリポジトリー検証（Docker/Maven/NPM)

# はじめに
業務でプライベートなリポジトリーとしてSonatype Nexus(OSS)を使っている。
対象はDocker/Maven/NPMである。
使い方を考える目的で検証した内容を残す。（Nexus3前提。）

時間がないけど要点を記録しようと作成した記事です。、あわてて作成したため、ミス等が含まれている可能性がそこそこあります。。

# 基本情報
## リポジトリーのフォーマット
Sonatype　Nexusがサポートするリポジトリーのフォーマットはいろいろある。
今回は、Docker/Maven/NPMを対象に検討。
[Supported Formats](https://help.sonatype.com/repomanager3/supported-formats)

## リポジトリーのタイプ
### 概念
はじめに覚えておく必要がある概念として、Nexusのリポジトリーのタイプがある。

* **Group**：HostedやProxyタイプのリポジトリーをまとめて1つのURLを提供できる。
* **Hosted**：プライベートなリポジトリーとして定義するもの。NexusにHostされる。
* **Proxy**：キャッシュ・プロキシー的に利用できるリポジトリー。（LAN内で開発を行う場合等でインターネットに接続可能なサーバーや端末が制限されるようなケースで、インターネット上のリポジトリーの情報をcacheしLAN内に共有する等の対応がとれる。）

正式な説明は以下を参照。
[Lesson 3: Repository Types](https://help.sonatype.com/learning/repository-manager-3/repository-management-basics/lesson-3%3A-repository-types)

### 制約

* Groupを利用すると、情報を**取得**（docker pull、mvn install、npm install）する際に指定するURLを1つに統一できる。
* しかし、情報を**登録**（docker push、mvn deploy、npm publish）する際に指定するURLとしては**利用できない。**（deploy先のURLはhostedのURLを個別に指定する必要がある。）

機能拡張要望のIssueが起票されている。voteが37ほどある。（以下参照。）
[allow deployment to group repositories](https://issues.sonatype.org/browse/NEXUS-10471)

## 設定手順
基本的には下記を参考にした。
[Using Nexus 3 as Your Repository – Part 1: Maven Artifacts](https://blog.sonatype.com/using-nexus-3-as-your-repository-part-1-maven-artifacts)
[Using Nexus 3 as Your Repository – Part 2: npm Packages](https://blog.sonatype.com/using-nexus-3-as-your-repository-part-2-npm-packages)
[Using Nexus 3 as Your Repository – Part 3: Docker Images](
https://blog.sonatype.com/using-nexus-3-as-your-repository-part-3-docker-images)

# 設定例（検証メモ）
（注）以降の設定例はあくまで簡易検証の結果のため、本番運用の際には、単位や名前などはしっかり考える必要がある。（特に、私自身はNPMはあまり詳しくないので、詳しい人と相談したいところ。）

## Nexusリポジトリー構造
| Name             |Format |Type   |URL                                            |port|
|:-----------------|:------|:------|:----------------------------------------------|:---|
| docker-all       |docker |group  |https://example.com/nexus/repository/docker-all|5000|
| docker-myrepo    |docker |hosted |https://example.com/nexus/repository/docker-myrepo|5001|
| docker-hub       |docker |proxy  |https://example.com/nexus/repository/docker-hub||
| maven-public       |maven2 |group  |https://example.com/nexus/repository/maven-public||
| maven-mysnapshots |maven2 |hosted |https://example.com/nexus/repository/maven-mysnapshots||
| maven-myreleases  |maven2 |hosted |https://example.com/nexus/repository/maven-myreleases||
| maven-central 　  |maven2 |proxy |https://example.com/nexus/repository/maven-central||
| npm-all      |npm |group  |https://example.com/nexus/repository/npm-all||
| npm-myrepo   |npm |hosted  |https://example.com/nexus/repository/npm-myrepo||
| npm-registry     |npm |proxy  |https://example.com/nexus/repository/npm-registry||
※docker-hub：https://registry-1.docker.io
※maven-central：https://repo1.maven.org/maven2/
※npm-registry：https://registry.npmjs.org/

## Docker
### Nexusリポジトリー構造
* 「docker-all」グループに「docker-myrepo」と「docker-hub」を含める 

### クライアントからのアクセス
イメージの取得（groupのreositoryで指定したポートを使う）

```cmd
$ docker login example.com:5000
$ docker pull example.com:5000/docker-all/jboss:15.0.1.Final
```

イメージの登録（hostedのrepositoryで指定したポートを使う）

```cmd
$ docker push example.com:5001/docker-myrepo/jboss:15.0.1.Final
```

## Maven
### Nexusリポジトリー構造
* 「maven-public」グループに「maven-central」と「maven-mysnapshots」と「maven-myreleases」を追加。

### クライアントからのアクセス
* mirrorとしてライブラリー類を取得するためのURLについてはsettings.xmlにて指定

```xml:settings.xml
  <mirrors>
    <mirror>
      <id>my-nexus</id>
      <name>My Central Mirror</name>
      <url>http://example.com/nexus/repository/maven-public/</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
```

mirrorの使い方そのものについては以下を参照。
[Apache MavenでリポジトリのMirrorを設定する](https://kazuhira-r.hatenablog.com/entry/2019/01/14/222933)


* デプロイ先は、pom.xmlの「distributionManagement」セクションで指定。（認証情報は必要に応じてsettings.xmlに指定。）

```xml:pom.xml
    <distributionManagement>
        <repository>
            <id>nexus</id>
            <name>maven-releases</name>
            <url>https://example.com/nexus/repository/maven-myreleases/</url>
        </repository>
        <snapshotRepository>
            <id>nexus</id>
            <name>maven-snapshots</name>
            <url>https://example.com/nexus/repository/maven-snapshots/</url>
        </snapshotRepository>
    </distributionManagement>
```
## NPM
### Nexusリポジトリー構造
* 「npm-all」グループに「npm-myrepo」と「npm-registry」を登録。

### クライアントからのアクセス
* .npmrcにinstall時にパッケージの取得用のproxyのURLを追加。
* _authに指定している値はユーザー認証情報をbase64で暗号化したもの。（echo -n 'myuser:mypassword' | openssl base64、等で生成する。）
* NexusのサーバーのRealmsの設定画面にて事前に「npm Bearer Token Realm」を有効にしておく必要がある。

```.proc:.npmrc
registry=https://example.com/nexus/repository/npm-all/
_auth="YWRtaW4vYWRtaW4xMjM="
```

* package.jsonにPublish用のリポジトリーを追加（下記の"publishConfig"セクションを参照。）

```json:package.json
{
  "name": "hello-hanako",
  "version": "0.0.1",
  "description": "self study to use npm repositories",
  "main": "index.js",
  "author": "Hanako Yamada",
  "license": "MIT",
  "devDependencies": {
    "http": "0.0.0"
  },
  "publishConfig": {
    "registry": "https://example.com/nexus/repository/npm-myrepo/"
  }
}
```

以上。