---
# System prepended metadata

title: Sonatype Nexus 建置
tags: [工具]

---

# Sonatype Nexus 建置

Sonatype Nexus 是用來集中管理、快取與分發二進位套件（artifacts）的伺服器。它不是存放原始碼，而是存放編譯後的元件（像 JAR、npm 套件、Docker image、PyPI 套件、NuGet 等）。

## 透過 podman 安裝 Nexus

### 安裝 podman

```
$ curl -fsSL -o podman-linux-amd64.tar.gz https://github.com/mgoltzsche/podman-static/releases/latest/download/podman-linux-amd64.tar.gz

$ tar -zxvf podman-linux-amd64.tar.gz;cd podman-linux-amd64
```
* 使用 rsync 複製 podman 執行檔案，並且會把原本會被覆寫的檔案移到備份目錄
```
$ sudo rsync -aHAX --numeric-ids --info=progress2 \
  --backup --backup-dir="/root/usr-backup-$(date +%F_%H%M%S)" \
  ./usr/ /usr/
```

```
$ sudo mkdir -p /etc/containers

$ sudo rsync -aHAX --no-o --no-g --info=progress2 \
  --backup --backup-dir="/root/etc-containers-backup-$(date +%F_%H%M%S)}" \
  ./etc/containers/ /etc/containers/
```

```
$ which podman
/usr/local/bin/podman

$ sudo podman version
Client:       Podman Engine
Version:      5.6.0
API Version:  5.6.0
Go Version:   go1.24.6
Built:        Thu Jan  1 08:00:00 1970
OS/Arch:      linux/amd64
```
* 如果 podman 需要使用 rootless ，還要安裝以下套件
```
$ sudo apt install -y uidmap
```
### 安裝 Nexus

```
$ sudo mkdir -p /nexus/nexus-data 

$ sudo chown -R 200 /nexus/nexus-data

$ sudo podman run -d -p 8081:8081 -p 8082:8082 --privileged --name nexus -v /nexus/nexus-data:/nexus-data --ulimit nofile=65536:65536 docker.io/sonatype/nexus3
```
* 如果離線環境需做以下設定
```
$ sudo mkdir -p /nexus/nexus-data/etc

$ sudo nano /nexus/nexus-data/etc/nexus.properties
# 停用建立預設儲存庫
nexus.skipDefaultRepositories=true
# 停用OSS索引漏洞檢查
nexus.ossindex.plugin.enabled=false

$ sudo chown -R 200:200 /nexus/nexus-data

$ sudo podman run -d -p 8081:8081 -p 8082:8082 --privileged --name nexus -v /nexus/nexus-data:/nexus-data --ulimit nofile=65536:65536 docker.io/sonatype/nexus3
```



* 檢視 admin 帳號密碼

```
$ cat /nexus/nexus-data/admin.password
ab81e52a-d923-462a-9a7b-225166e20c67
```

## 登入 Nexus
* 右上角登入

![image](https://hackmd.io/_uploads/rJN2yn1hee.png)

* 設定新密碼

![image](https://hackmd.io/_uploads/H1DR1h12xl.png)

* 允許匿名者登入

![image](https://hackmd.io/_uploads/S1Jgxhy3xx.png)

## 建立 Blob Stores
Nexus 的 Blob Stores 是用來保存「原始二進位檔案」（artifact binaries / blobs）的儲存池，也就是所有套件檔案（jar、tar、docker layer、npm package 等）實際的位元組內容都放在 blob store；Repository 則是指向這些 blob 的索引與 metadata。



* 創建一個名稱為 `apt` 的 Blob Stores


![image](https://hackmd.io/_uploads/rkIuTmehlx.png)

![image](https://hackmd.io/_uploads/ryBgRQg3gx.png)


## 新增 apt proxy 倉庫
透過 nexus 當 ubuntu 的 proxy 倉庫來源，ubuntu 只要安裝套件就會從 nexus 下載，並提供套件。


![image](https://hackmd.io/_uploads/SkzXy4e2gl.png)

![image](https://hackmd.io/_uploads/S1THJ4xnxe.png)

![image](https://hackmd.io/_uploads/Byh1gNg3eg.png)

> 使用 `http://tw.archive.ubuntu.com/ubuntu` 位置


* Blob Stores 選擇我們剛剛創建的 `apt` Blob Stores 

![image](https://hackmd.io/_uploads/BJkwxVl2lg.png)


![image](https://hackmd.io/_uploads/HJRjgEx2xx.png)

* 複製連結

![image](https://hackmd.io/_uploads/ByHyZ4g2ex.png)


* 修改 ubuntu24.04 的更新套件清單來源

```
# 修改前先備份
$ sudo cp /etc/apt/sources.list.d/ubuntu.sources ubuntu.sources

$ sudo nano /etc/apt/sources.list.d/ubuntu.sources
Types: deb
URIs: http://10.10.7.20:8081/repository/apt-proxy/           # 修改
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

Types: deb
URIs: http://10.10.7.20:8081/repository/apt-proxy/           # 修改
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
```
* 更新套件清單
```
$ sudo apt update
```


* 可以看到 Nexus 正在「對外提供」Ubuntu 釋出的 metadata（索引）與對應的套件內容（.deb 的索引/檔案位置）。


![image](https://hackmd.io/_uploads/rJCMEVx3ll.png)

### 透過 Nexus 安裝套件
* 列出 net-tools 套件來源，可以看到都是從 Nexus 提供
```
$ sudo apt-cache madison net-tools
 net-tools | 2.10-0.1ubuntu4.4 | http://10.10.7.20:8081/repository/apt-proxy noble-updates/main amd64 Packages
 net-tools | 2.10-0.1ubuntu4.4 | http://10.10.7.20:8081/repository/apt-proxy noble-security/main amd64 Packages
 net-tools | 2.10-0.1ubuntu4 | http://10.10.7.20:8081/repository/apt-proxy noble/main amd64 Packages
```


* 安裝套件
```
$ sudo apt-get install net-tools
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  net-tools
0 upgraded, 1 newly installed, 0 to remove and 185 not upgraded.
Need to get 204 kB of archives.
After this operation, 811 kB of additional disk space will be used.
Get:1 http://10.10.7.20:8081/repository/apt-proxy noble-updates/main amd64 net-tools amd64 2.10-0.1ubuntu4.4 [204 kB]
......
```


* 可以看到 `apt-proxy` Browse 多了 net-tools 套件包，之後只要 ubuntu 指向到 Nexus 就可以透過 Nexus 安裝套件

![image](https://hackmd.io/_uploads/BkklB4lnxx.png)


## 新增 apt host 倉庫
手動上傳 deb 檔案到 nexus，並且透過 nexus 安裝套件

* 在 nexus 主機上執行
```
# 執行後輸入密碼
$ sudo gpg --gen-key
gpg (GnuPG) 2.4.4; Copyright (C) 2024 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Note: Use "gpg --full-generate-key" for a full featured key generation dialog.

GnuPG needs to construct a user ID to identify your key.

Real name: nexus
Email address:
You selected this USER-ID:
    "nexus"

Change (N)ame, (E)mail, or (O)kay/(Q)uit? o
......
```

* 匯出公鑰
```
$ sudo gpg -a -o nexus_pub.asc --export nexus

$ ls -l nexus_pub.asc
-rw-r--r-- 1 root root 624 Sep 23 23:04 nexus_pub.asc
```
* 匯出私鑰，並輸入創建時的密碼

```
$ sudo gpg -a -o nexus_pri.asc --export-secret-key nexus

$ ls -l nexus_pri.asc
-rw------- 1 root root 849 Sep 23 23:05 nexus_pri.asc
```

* 創建 apt host 倉庫

![image](https://hackmd.io/_uploads/BJZoPNenxx.png)
![image](https://hackmd.io/_uploads/r1N3wNx2gx.png)

* 輸入私鑰以及密碼

![image](https://hackmd.io/_uploads/SyBlOVx3ex.png)
![image](https://hackmd.io/_uploads/Hk1E_4e2lg.png)



### 手動上傳 deb 檔案

* 上傳 `net-tools_2.10-0.1ubuntu4.4_amd64.deb` 檔案

![image](https://hackmd.io/_uploads/ByOl1Sx2xe.png)


![image](https://hackmd.io/_uploads/H1z7krxhll.png)

* 在 `apt-host` Browse 可以看到上傳的檔案

![image](https://hackmd.io/_uploads/SJaL1Hghgg.png)

### 客戶端安裝自己上傳到 nexus 的套件
* 到客戶端將公鑰放到 `/etc/apt/trusted.gpg.d/` 目錄下
```
$ sudo cp nexus_pub.asc /etc/apt/trusted.gpg.d/
```
![image](https://hackmd.io/_uploads/S1Ef04ehgg.png)

* 新增套件清單來源
```
# 修改前先備份
$ sudo cp /etc/apt/sources.list.d/ubuntu.sources ubuntu.sources

$ sudo nano /etc/apt/sources.list.d/ubuntu.sources
Types: deb
URIs: http://10.10.7.20:8081/repository/apt-host/
Suites: noble
Components: main restricted universe multiverse
Signed-By: /etc/apt/trusted.gpg.d/nexus_pub.asc


Types: deb
URIs: http://tw.archive.ubuntu.com/ubuntu/
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

Types: deb
URIs: http://security.ubuntu.com/ubuntu/
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
```



> 或是使用舊的方式修改套件來源，修改 `/etc/apt/sources.list`
```
$ sudo nano /etc/apt/sources.list
# Ubuntu sources have moved to /etc/apt/sources.list.d/ubuntu.sources
deb [trusted=yes] http://10.10.7.20:8081/repository/apt-host/ noble main
```
* 更新套件清單
```
$ sudo apt update
Hit:1 http://10.10.7.20:8081/repository/apt-host noble InRelease
Hit:2 https://download.docker.com/linux/ubuntu noble InRelease
Hit:3 http://tw.archive.ubuntu.com/ubuntu noble InRelease
Hit:4 http://tw.archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:5 http://tw.archive.ubuntu.com/ubuntu noble-backports InRelease
Hit:6 http://security.ubuntu.com/ubuntu noble-security InRelease
......
```
* 列出 `net-tools` 套件清單來源
```
$ sudo apt-cache madison net-tools
 net-tools | 2.10-0.1ubuntu4.4 | http://10.10.7.20:8081/repository/apt-host noble/main amd64 Packages
 net-tools | 2.10-0.1ubuntu4.4 | http://tw.archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages
 net-tools | 2.10-0.1ubuntu4.4 | http://security.ubuntu.com/ubuntu noble-security/main amd64 Packages
 net-tools | 2.10-0.1ubuntu4 | http://tw.archive.ubuntu.com/ubuntu noble/main amd64 Packages
```

* 指定安裝`net-tools` 套件的版本號，並且可以看到套件來源是從 nexus 來的

```
$ sudo apt install net-tools=2.10-0.1ubuntu4.4
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  net-tools
0 upgraded, 1 newly installed, 0 to remove and 185 not upgraded.
Need to get 204 kB of archives.
After this operation, 811 kB of additional disk space will be used.
Get:1 http://10.10.7.20:8081/repository/apt-host noble/main amd64 net-tools amd64 2.10-0.1ubuntu4.4 [204 kB]
Fetched 204 kB in 0s (6,507 kB/s)
.....
```
* 檢查版本與 apt 認到的來源
```
$ sudo apt-cache policy net-tools
net-tools:
  Installed: 2.10-0.1ubuntu4.4
  Candidate: 2.10-0.1ubuntu4.4
  Version table:
 *** 2.10-0.1ubuntu4.4 500
        500 http://10.10.7.20:8081/repository/apt-host noble/main amd64 Packages
        500 http://tw.archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages
        500 http://security.ubuntu.com/ubuntu noble-security/main amd64 Packages
        100 /var/lib/dpkg/status
     2.10-0.1ubuntu4 500
        500 http://tw.archive.ubuntu.com/ubuntu noble/main amd64 Packages
```

## 新增 docker host 倉庫
透過 nexus 可以當 image registry，提供 container image 下載

* 創建 docker host 的 Blob Stores

![image](https://hackmd.io/_uploads/ByJl4Hxhlx.png)
![image](https://hackmd.io/_uploads/rkgBZ4Hg3le.png)


* 創建 docker host 倉庫

![image](https://hackmd.io/_uploads/HyKvXBxnge.png)
![image](https://hackmd.io/_uploads/r1LK7Sengl.png)

* 開放 `8082` port 提供上傳跟下載 image

![image](https://hackmd.io/_uploads/rk6v4Behel.png)

* Nexus UI → Security → Realms : `Docker Bearer Token Realm` 移至右側

![image](https://hackmd.io/_uploads/ByRHKHehxg.png)

### 設定 docker client

```
$ sudo nano /etc/docker/daemon.json
{
  "log-level": "warn",
  "log-driver": "json-file",
  "insecure-registries": ["10.10.7.20:8082"],     # 新增 nexus 位置
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  }
}
```
```
$ sudo systemctl daemon-reload

$ sudo systemctl restart docker
```
* 成功登入 
```
$ sudo docker login 10.10.7.20:8082
Username: admin
Password:

WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/

Login Succeeded
```
* 上傳 image 到 nexus
```
$ sudo docker push 10.10.7.20:8082/nginx:latest
```
* 在 nexus 上可以看到這張 image

![image](https://hackmd.io/_uploads/rkYS9rlnxe.png)

* 在別台機器可以成功 pull 這張 image

```
$ sudo docker pull 10.10.7.20:8082/nginx:latest
```









## 參考

https://help.sonatype.com/en/sonatype-product-overview.html


https://support.sonatype.com/hc/en-us/articles/360049884673-Considerations-For-NXRM-3-Inside-Air-Gapped-Restricted-Firewalled-and-DMZ-Networks