使用 Docker 搭建私有軟件倉庫 Nexus 3

  • 2020 年 3 月 13 日
  • 筆記

本文使用「署名 4.0 國際 (CC BY 4.0)」許可協議,歡迎轉載、或重新修改使用,但需要註明來源。 署名 4.0 國際 (CC BY 4.0)

本文作者: 蘇洋

創建時間: 2020年03月08日 統計字數: 4927字 閱讀時間: 10分鐘閱讀 本文鏈接: https://soulteary.com/2020/03/08/use-docker-to-build-private-software-repositories-nexus-v3.html


使用 Docker 搭建私有軟件倉庫 Nexus 3

一年前,我曾經寫過一篇《遷移 Nexus 軟件倉庫拾遺》,在文章中有提到一些常見的問題,最近在升級改造相關基礎技術設施,覺得應該把經驗記錄下來,造福有相關需求的同學、團隊。

這款 sonatype 公司出品的 Nexus Repository Manager,打 3.x 版本從15年開坑開始到現在,每半個月更新一次,非常值得信賴。目前官方數據顯示,全球有超過十萬的個人/團隊在使用這個企業級的軟件。

本文將基於 Docker 和 Traefik v2 聊聊如何搭建一個穩定高效的軟件倉庫,畢竟這兩年里,這個倉庫幾乎不需要額外的打理,為我個人和團隊默默提供着可靠的高性能私有服務。

寫在前面

說起技術相關的「倉庫」,我們一般會想到的是代碼倉庫,比如之前文章中寫到的 GitLab、Gitea、Gogs。

然而這些代碼倉庫一般只用於存儲尚未編譯處理的原始程序,而對於編譯產物(artifact)的管理一般是不做處理的,即使有這類功能,也相對比較孱弱,比如當前的GitLab。

加之當前研發過程中,非常流行的高頻率持續集成生產行為,軟件倉庫很多時候,除了作為最後的「交付儲存池」,還需要肩負着一些額外的責任:

  • 提供 「安全可靠的官方軟件源鏡像」
  • 提供 「軟件包安全掃描」
  • 提供「軟件包集中審計平台」

類似的高級需求,讓軟件倉庫的競爭也激烈了起來,除了 Nexus 外,你或許還聽說過 Harbor、Portus。

Nexus 的官方定位是一款支持通用格式的軟件倉庫,對於存儲格式並不敏感

也就是說,你可以用它來託管 類似 Ubuntu 的 Linux 軟件源、可以用來做 NPM 倉庫、也可以用來提供 Maven、Docker、Go、Python、Ruby…你能想到的各種語言、軟件所需要的「鏡像」。

介紹的夠多了,我們來正式進入搭建環節。

基礎搭建

為了讓應用域名和SSL證書能夠更加容易的掛載到服務器上,並且便於後續管理。這裡依舊使用 Traefik 2.x 版本作為應用網關,相關的內容,你可以從之前的一些文章中做簡單了解,比如:這篇和這篇。

這裡我們啟動一個域名為 nexus.lab.io,並且支持 HTTP 自動跳轉 HTTPS 的全能倉庫,進程遇到錯誤,會自動嘗試重新啟動。

滿足上面需求的容器編排配置非常簡單,只需要不到五十行代碼。

version: "3.6"    services:      nexus3:      container_name: nexus.lab.io      image: sonatype/nexus3:3.21.1      environment:        - INSTALL4J_ADD_VM_PARAMS=-Xms2g -Xmx2g -XX:MaxDirectMemorySize=2g -Djava.util.prefs.userRoot=/nexus-data/javaprefs -Duser.timezone=Asia/Shanghai      restart: always      expose:        - 8081      volumes:        - /etc/localtime:/etc/localtime:ro        - /etc/timezone:/etc/timezone:ro        - /var/run/docker.sock:/var/run/docker.sock        - ./nexus-data:/nexus-data      networks:        - traefik      labels:        - "traefik.enable=true"        - "traefik.docker.network=traefik"        - "traefik.http.middlewares.nexus-bechind-proxy.headers.customrequestheaders.X-Forwarded-Proto=https"        - "traefik.http.routers.nexus-web.middlewares=https-redirect@file"        - "traefik.http.routers.nexus-web.entrypoints=http"        - "traefik.http.routers.nexus-web.rule=Host(`nexus.lab.io`)"        - "traefik.http.routers.nexus-web.service=nexus-backend"        - "traefik.http.routers.nexus-ssl.middlewares=content-compress@file,nexus-bechind-proxy"        - "traefik.http.routers.nexus-ssl.entrypoints=https"        - "traefik.http.routers.nexus-ssl.tls=true"        - "traefik.http.routers.nexus-ssl.rule=Host(`nexus.lab.io`)"        - "traefik.http.routers.nexus-ssl.service=nexus-backend"        - "traefik.http.services.nexus-backend.loadbalancer.server.scheme=http"        - "traefik.http.services.nexus-backend.loadbalancer.server.port=8081"      healthcheck:        test: ["CMD-SHELL", "curl -f localhost:8081 || exit 1"]      logging:          driver: "json-file"          options:            max-size: "10m"    networks:    traefik:      external: true

將上面的內容保存為 docker-compose.yml ,使用熟悉的 docker-compose up-d 啟動應用。

此刻可以使用 docker-compose logs-f 來觀察應用初始化過程是否出現錯誤情況,並等待瘋狂刷屏的日誌停止。

nexus.lab.io | -------------------------------------------------  nexus.lab.io |  nexus.lab.io | Started Sonatype Nexus OSS 3.21.1-01  nexus.lab.io |  nexus.lab.io | -------------------------------------------------

不論是你看到類似上面的日誌提示,還是使用 docker ps 看到下面標示為 healthy 的容器進程狀態,都說明 Nexus 已經正常啟動了起來。

a9b4ac5142e0        sonatype/nexus3:3.21.1                       "sh -c ${SONATYPE_DI…"   2 hours ago         Up 2 hours (healthy)      8081/tcp, 9100-9101/tcp                    nexus.lab.io

在瀏覽器中打開我們之前配置好的域名: nexus.lab.io,可以看到 Nexus 清爽的新版界面。

在去年的時候,Nexus的默認登陸賬號和密碼還是 adminadmin123。但是顯然現在官方意識到這是個錯誤的策略。

今年新的版本中,初始化的新實例,雖然默認賬號還是 admin,但是密碼已經改為了隨機生成的字符串,並且保存在只有擁有應用安裝權限的人才能看到的地方: /nexus-data/admin.password

因為我們使用容器啟動 Nexus,並將 Nexus 的數據文件掛載到了本地磁盤,所以此時,我們可以選擇兩個方式來讀取這個文件。

# 在啟動應用的目錄中執行  cat nexus-data/admin.password  # 或者直接使用 Docker CLI 執行容器命令  docker exec -it nexus.lab.io cat /nexus-data/admin.password

在輸入了正確的初始賬號和密碼後,新版軟件會人性化的引導我們設置新密碼,以及設置是否允許匿名用戶使用。

如果是個人使用,或者團隊在內網使用,可以勾選「允許匿名訪問」。

在聊一些高級使用方法之前,我們需要先了解它的一些基礎使用。

基礎使用

在正確登陸並進行過第一次初始化設置後,我們可以看到頂部的狀態欄多了一個齒輪按鈕。

點擊按鈕,進入管理後台,默認會停留在 「Repository」 菜單,在左側的側邊欄,選擇二級菜單「Repositories」,可以看到默認已經添加了不少常用的軟件倉庫支持。

這裡可能暫時沒有你想用的代碼倉庫,但是沒有關係,先從了解它提供軟件倉庫服務的基礎流程開始吧,畢竟所有倉庫都大同小異。

我們點開 maven-group 這個項目,可以清晰的看到這個 maven 軟件倉庫是如何工作的:

  • 先從 maven-release 獲取軟件包,找不到的話,繼續查找下一個類別的項目,這個倉庫是我們默認發佈軟件使用的。
  • 接着從 maven-snapshots 獲取軟件包,找不到的話,繼續查找下一個類別的項目,這個倉庫是我們發佈調試版本軟件包使用的。
  • 最後從 maven-central 獲取官方源軟件包,找不到的話,則宣告 「404 Not Found」。(默認源: https://repo1.maven.org/maven2/

你當然可以選擇添加更多來源的 倉庫類型,比如「阿里/騰訊鏡像」、「公司生產環境」、「公司測試環境」等等,以及調整Nexus的獲取響應順序來改變你在安裝軟件包時的體驗和預期結果。

至於如何配置 Maven 倉庫,應該不需要我教你了吧。至此 Nexus 的基礎搭建就完成了。

最後

考慮到內容篇幅,本篇內容就先到此為止。

接下來的內容,我將介紹如何使用 Nexus 搭建 Docker 倉庫、NPM 倉庫,以及一些設置細節。