# 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