Nexus 是支援 Nuget、Docker、Npm 等多種包的倉庫管理器,可用做私有包的儲存分發,快取官方包。本篇將手把手教學使用 Nexus 搭建自己的 NuGe t& Docker 私有倉庫。
私有化倉庫管理
支援許可權管理
快取依賴包
支援外掛機制和 REST API
成熟穩定強大
支援的倉庫/包管理
建立資料掛載目錄並賦予許可權:以 UID 200 的形式執行 mkdir ./data && chown -R 200 ./data
指定版本:sonatype/nexus3:3.61.0
預設埠:8081
指定存取字首:/
指定網路:devopsnetwork (docker network create devopsnetwork
)
部署伺服器 IP:192.168.123.214
建立 compose.yml
version: '3.1'
services:
nexus:
image: sonatype/nexus3:3.61.0
container_name: nexus_3_61
restart: always
environment:
# Nexus 上下文路徑
NEXUS_CONTEXT: /
# 指定jvm引數
INSTALL4J_ADD_VM_PARAMS: -Xms1g -Xmx1g -XX:MaxDirectMemorySize=3g
volumes:
# 需要先給許可權 chown -R 200 ./data
- ./data:/nexus-data
ports:
- "8081:8081"
networks:
- devopsnetwork
networks:
devopsnetwork:
external: true
執行:docker compose up -d
執行需要時間,耐心等待 2-3 分鐘,存取:http://192.168.123.214:8081/
可以看到提示預設 admin 的密碼在 ./data/admin.password ,獲取後點選右上角 Sign In 進行登入
登入成功會進行引導修改密碼 devops666 和禁用匿名存取
server {
listen 80;
listen 443 ssl;
server_name nexus.devops.test.com;
# allow large uploads of files
client_max_body_size 1G;
ssl_certificate /certs/nexus.devops.test.com/server.crt;
ssl_certificate_key /certs/nexus.devops.test.com/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://nexus_3_61:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
一個企業可能存在著多個團隊或專案組,每個團隊的包可以分開或者約定好不同的名稱字首
包的讀寫許可權需要分離,即上傳者和使用者分開,上傳者包含讀寫許可權,使用者只需要有存取許可權
許可權說明:檔案
拉取角色:pull-man ,設定許可權:nx-repository-view-*-*-browse
nx-repository-view-*-*-read
推播角色:push-man ,設定許可權:nx-component-upload
nx-repository-view-*-
-
拉取賬號:puller , 設定密碼 devops666,設定角色:pull-man
推播賬號:pusher,設定密碼 devops666,設定角色:push-man,nuget 使用的 APIKey 所以暫時沒有用到,後面管理 docker 的時候使用
推播 NuGet 包時需要使用,點選管理員頭像->NuGet API 金鑰->生成金鑰
上一步獲取了金鑰,還無法直接使用,還需要在設定中 Security>Realms 中啟用 NuGet API-Key Realm。
類似啟用的驗證方式,領域說明見檔案
預設 nuget 包託管是啟用了, 而為了防止包被惡意篡改,可以將 nuget-hosted 倉庫修改為禁用重新部署,多人協同開發時可防止包被被其他人覆蓋,相關檔案說明 。在設定了禁用重新部署時,推播重複包的時候將會返回 400 錯誤
因為前面設定關閉了匿名存取以及設定了相應的賬號,所以為了方便的從 Nexus 服務中拉取 Nuget 包,可以通過組態檔 nuget.config (檔案)來指定 nuget 源為 Nexus 服務 nexus.devops.test.com
指定設定節的名稱和源(預設使用 NuGet V3,V2 不需要加 index.json)
指定使用包源的賬號密碼
將其放到和解決方案同級目錄即可生效
nuget.config 檔案
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nexus.devops.test.com" value="https://nexus.devops.test.com/repository/nuget-group/index.json" />
</packageSources>
<packageSourceCredentials>
<nexus.devops.test.com>
<add key="Username" value="puller" />
<add key="ClearTextPassword" value="devops666" />
</nexus.devops.test.com>
</packageSourceCredentials>
</configuration>
從本地推播一個 NuGet 包到 Nexus 服務進行託管,需要兩步,打包,推播。為了更好的使用,可以結合指令碼來快速打包,以之前的一個計算欄位封裝為例將其打包成 NuGet 包推播到 Nexus 中
目錄結構如下
首先新建設定一個 .nuspec 模板,根據需要修改庫的相關資訊,nuspec 設定檔案
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Devops.Common.EvalSDK</id>
<version>0.0.15</version>
<authors>yimo</authors>
<description>計算欄位</description>
<projectUrl>https://github.com/yimogit/MeDevOps</projectUrl>
<tags>Devops.Common.EvalSDK</tags>
<repository type="git" url="https://github.com/yimogit/MeDevOps.git" branch="main"/>
</metadata>
<files>
<file src="..\Devops.Common.EvalSDK\bin\Release***.dll" target="lib" />
<file src="..\Devops.Common.EvalSDK\bin\Release***.pdb" target="lib" />
</files>
</package>
打包庫的參考,多個版本使用 TargetFrameworks
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.1;netcoreapp3.1;net5.0;net7.0;</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<DocumentationFile>bin$(Configuration)$(TargetFramework)\Devops.Common.EvalSDK.xml</DocumentationFile>
</PropertyGroup>
</Project>
新建打包指令碼,修改金鑰和地址,後續每次執行前修改版本號,執行即可
#!/bin/bash
pwd
current_dir=`pwd`
#nuget api金鑰
nuget_key="aa7890bf-8dfb-33e3-bed9-c1571e5b9b96"
#託管倉庫地址
nuget_source="https://nexus.devops.test.com/repository/nuget-hosted/"
#包的版本
package_version="0.0.2"
#包名
nupkg_pakcage_name="Devops.Common.EvalSDK.${package_version}.nupkg"
#專案庫路徑
csproj_path="../Devops.Common.EvalSDK/Devops.Common.EvalSDK.csproj"
#包設定
nuspec_path="Devops.Common.EvalSDK.nuspec"
#nuspec path , relative csproj path
nuspec_path_relative_csproj="../pack/Devops.Common.EvalSDK.nuspec"
#git pull
#刪除舊版本
rm -f nupkg_pakcage_name
cd ${current_dir}
#替換版本號
sed -i 's|<version>.*</version>|<version>'${package_version}'</version>|g' ${nuspec_path}
echo pack ${nupkg_pakcage_name}
#打包nupkg檔案到當前pack目錄 包名.x.x.x.nupkg
dotnet pack ${csproj_path} -p:NuspecFile=${nuspec_path_relative_csproj} -c Release --output ../pack -v m
#判斷是否打包成功
echo
if [ ! -f "${nupkg_pakcage_name}" ]; then
echo "pack ${nupkg_pakcage_name} is error"
exit -1
fi
#推播包
echo push ${nupkg_pakcage_name}
dotnet nuget push ${nupkg_pakcage_name} -k ${nuget_key} -s ${nuget_source}
執行成功,在使用 Nexus 源的包管理器中就能搜尋使用了
當前版本支援 docker 映象的管理,使用發現通過 docker-group 推播映象是需要企業版的,不過還是可以根據拉取和推播的域名/埠分開來達到推播的效果。
可以先看下面這個流程圖,再看後續如何設定就很清晰了
許可權說明:檔案 這裡給了所有倉庫的拉取以及推播許可權,和前面一樣,可以只建立對應的 docker 許可權
拉取角色:pull-man ,設定許可權:nx-repository-view-*-*-browse
nx-repository-view-*-*-read
推播角色:push-man ,設定許可權:nx-component-upload
nx-repository-view-*-
-
拉取賬號:puller , 設定密碼 devops666,設定角色:pull-man
推播賬號:pusher,設定密碼 devops666,設定角色:push-man
和前面 nuget 的三個倉庫一樣,docker 的倉庫也新建三個
push.nexus.devops.test.com
(開源版不支援使用 group 推播映象)https://registry-1.docker.io
並使用 Use Docker Hub 的索引根據檔案與實際使用,https 是必須的,所以依託於之前 nginx 的證書申請 以及 dns 服務的使用,我們可以在區域網中設定域名來存取 nexus3 提供的 docker 映象倉庫服務
預設拉取使用 nexus.devops.test.com
,推播則使用:push.nexus.devops.test.com
以下為 nginx 的設定,根據官方檔案所修改,主要替換其中域名與證書,因為是區域網的自定義域名,需要在使用者端安裝證書才不會有不安全的提示,同理 linux 下使用,也需要安裝對應 pem 證書
server {
listen 80;
listen 443 ssl;
server_name nexus.devops.test.com;
# allow large uploads of files
client_max_body_size 10G;
ssl_certificate /certs/nexus.devops.test.com/server.crt;
ssl_certificate_key /certs/nexus.devops.test.com/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /v2 {
proxy_pass http://nexus_3_61:8081/repository/docker-group/$request_uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "https";
}
location /v1 {
proxy_pass http://nexus_3_61:8081/repository/docker-group/$request_uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "https";
}
location / {
proxy_pass http://nexus_3_61:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Proto "https";
}
}
server {
listen 80;
listen 443 ssl;
server_name push.nexus.devops.test.com;
# allow large uploads of files
client_max_body_size 10G;
ssl_certificate /certs/push.nexus.devops.test.com/server.crt;
ssl_certificate_key /certs/push.nexus.devops.test.com/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /v2 {
proxy_pass http://nexus_3_61:8081/repository/docker-hosted/$request_uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "https";
}
location /v1 {
proxy_pass http://nexus_3_61:8081/repository/docker-hosted/$request_uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "https";
}
location / {
proxy_pass http://nexus_3_61:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Proto "https";
}
}
過載設定生效後存取確認 https 是否生效,以及可以檢視 restapi 介面是否可以存取
至此,私有的 docker 倉庫已經搭建好了,本文基於區域網的自定義域名,如果是伺服器,正常解析域名到伺服器,申請 ssl 證書等踩的坑都會少一點。接下來就是如何使用 nexus.devops.test.com
,push.nexus.devops.test.com
來拉取&推播 docker 映象了
因為本文域名是區域網中的 dns 解析,所以需要在 linux 中設定 dns,確保域名能夠存取到 nexus 存取,伺服器則不需要考慮,跳過直接使用即可
編輯 dns 組態檔:vi /etc/resolv.conf
nameserver 192.168.123.214
nameserver 114.114.114.114
寫入後重啟網路生效:systemctl restart NetworkManager
ping nexus.devops.test.com
ip 是 192.168.123.214 就對了
cp ./myCA.pem /etc/pki/ca-trust/source/anchors/
update-ca-trust -f
ps aux | grep openssl
的 pid: xxx xxx pid 號 pts/0 R+,kill 掉 pid,會自動重新啟動 kill pid號
) 或直接重啟伺服器生效(reboot
)因為是自簽證書,如果未安裝證書就使用 docker login nexus.devops.test.com
會提示:tls: failed to verify certificate: x509: certificate signed by unknown authority
docker login nexus.devops.test.com -u puller -p devops666
docker login push.nexus.devops.test.com -u pusher -p devops666
登入成功後可以檢視設定的源:cat /root/.docker/config.json
docker pull nexus.devops.test.com/nginx
docker login push.nexus.devops.test.com -u pusher -p devops666
docker tag nexus.devops.test.com/nginx
push.nexus.devops.test.com/nginx_custom
docker push push.nexus.devops.test.com/nginx_custom
資料目錄不設定許可權啟動失敗
資料目錄許可權:此目錄需要可由 Nexus 寫入 程序,以 UID 200 的形式執行
chown -R 200 ./data
NuGet V2 和 NuGet V3 設定對比
NuGet 的 API 金鑰生成,但是沒有啟用領域設定,無法推播包到 Nexus
禁用重新部署時,但是推播了相同的包時,會返回 400
Linux 上安裝證書,看到很多資料都是執行update-ca-trust
就結束了,按著步驟來設定了但無效。最後才想到可能是因為沒生效,重啟完發現真是,想了下應該是 openssl 需要重啟,試了下果然,才得以解決進行下一步。如果不適用區域網域名問題會少很多~
Docker 倉庫新建的時候那個協定設定理解了半天,找到的文章都是設定埠,設定域名的方式也是一點點理解檔案,然後試出來的。
解決了之前 Windows 生成自簽證書時不能自動輸入資訊的問題,需要像下面這樣寫,參考
winpty openssl req -new -key $DOMAIN/server.key -out $DOMAIN/server.csr -subj "//C=CN\ST=Beijing\L=Beijing\O=TestOrganization\OU=TestOU\CN=TestRootCA\[email protected]"
本篇嘔心瀝血,絕對是值得收藏的,同時也希望看官們能順手再點個贊~
書山有路勤為徑,學海無涯苦作舟。
沉迷學習,無法自拔。jpg