從零開始通過 Artifactory 搭建公網的 maven 倉庫

劉小蠻發表於2017-06-28

來自我的 Blog Danny's Dream

起因

最近在給公司的 SDK ,做一個 maven 的倉庫,方便 CP 嵌入。花了整兩天的時間,身為移動開發的我之前沒怎麼接觸過伺服器相關的內容,這裡做一個記錄和分享, 並且網上大部分的教程都是如何搭建本地倉庫的
用到了以下幾個內容

  • Artifactory jfrog 家的用來做倉庫管理和持續整合【配合 Jenkins 】的工具 免費版就夠用了 【支援 maven gradle】
  • Maven Maven是Java開發者中流行的構建工具,Maven的好處之一是可以幫助減少構建應用程式時所依賴的軟體構件的副本,Maven建議的方法是將所有軟體構件儲存於一個叫做repository的遠端倉庫中。
  • Gradle 是 Android Studio 中帶的自動化構建工具 是 maven 的擴充套件
  • Nginx 是一個高效能的HTTP和反向代理伺服器,也是一個IMAP/POP3/SMTP伺服器,用來處理代理的。

之前沒有怎麼操作過 Linux 的伺服器,這次經歷還是很有趣的,把遇到的問題記錄一下。

連線主機

運維提供的伺服器是 Linux 的,通過 ssh 方式來連線伺服器。

ssh xxx.xxx.xxx.xxx複製程式碼

這一步遇到的問題是 公司的 Linux 登入驗證是提供了一個 私有的 ssh key,
我本地配置的是 GitHub 的 ssh key,預設連線的時候用的是 GitHub 的 key。
運維給出的方式是通過 -i 加上 key 的路徑來登陸。

ssh -i dan-key xxx.xxx.xxx.xxx複製程式碼

這樣的方式雖然可以,但是每次都這麼輸入未免太麻煩了。
網上查了,提供了以下的方式解決的我的需求。
在 .ssh 檔案下面建一個 config 檔案如下配置

# github
Host github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa 

# maven
Host 192.168.111.11
User liudan 
PreferredAuthentications publickey
IdentityFile ~/.ssh/liudan-server複製程式碼

這樣就能完美解決了多 ssh key 的登入情況。

安裝 Artifactory

Artifactory 的官網 www.jfrog.com/open-source…
通過 java - version 檢查 java 環境
他需要的是 java8 的環境,如果沒有的話,要先給伺服器搭建 jdk8 的環境。
但是裡面的下載好像不能通過,Linux 的 wget 指令直接在伺服器內部進行下載。
我是在本地下載完之後,通過 scp 指令再拷貝到伺服器的【這裡也需要 ssh key】
移動到伺服器之後,通過 unzip 解壓。
得到下面的內容


進入到 bin 資料夾中有

注意三個檔案:

  • artifactory.sh 用來直接執行 artifactory 的程式,執行之後就會開啟 tomcat ,並且部署一個視覺化的網頁
    http:///artifactory/webapp/#/home你的ip>複製程式碼
  • installService.sh 這個是用來安裝 artifactory 的服務,可以作為服務在後臺自動執行,並會隨伺服器一起啟動【我猜的。。我看他是移動到了init的目錄下面】
  • artifactoryManage.sh 是用來做服務管理的提供幾種方式
       {start|stop|restart|redebug|status|check} 這個就不翻譯了,可以看到當前的狀態。
       使用方法這樣  ./artifactoryManage.sh check  加命令複製程式碼

注意的地方:
一般的教程都是讓你,直接執行 artifactory.sh 就可以啟動了。其實服務端更多的時候希望他是作為後臺常駐的。
所以這裡我們要執行的 installService.sh 指令碼
執行完之後 會看到給我們的提示幫我們移動到了 /etc/init.d/artifactory 目錄中
通過這兩個指令可以檢查和啟動後臺的服務。
/etc/init.d/artifactory check
/etc/init.d/artifactory start

這裡要注意 artifactory.default 中的 user 的配置 !
預設的是設定為 artifactory 的,但是 artifactory 使用者的許可權不夠【可能是我們伺服器配置的原因】,
會導致 /etc/init.d/artifactory start 由於許可權不夠而無法啟動 tomcat 的。這是當時困擾了我很久問題。

按照上面的操作,你應該已經能看到 Artifactory 的介面了
剛進去的時候會讓你設定 admin 密碼,同時設定倉庫型別。
都完成之後是這樣的介面:

這裡學到了如下幾個 Linux 指令

ps -ef | grep artifactory複製程式碼

ps -ef 檢視所有的程式,通過 grep 進行過濾,可以看到和 artifactory 相關的程式,拿到 pid 之後
通過

kill -9 目標id複製程式碼

就可以停止目標程式

Lib 的上傳

下面的內容就相對簡單了。
在你的 lib 的工程的 build.gradle 中增加如下外掛的依賴

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0'
        classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:latest.release'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}複製程式碼

接著在你需要上傳的 lib 的 module 的 build.gradle 的檔案中增加如下配置:
這個是用來配置上傳的路徑和賬號資訊的

artifactory {
    contextUrl = MAVEN_LOCAL_PATH
    publish {
        repository {
            // 需要構建的路徑
            repoKey = 'gradle-release-local'

            username = 'admin'
            password = '這裡是密碼'
        }
        defaults {
            // Tell the Artifactory Plugin which artifacts should be published to Artifactory.
            publications('aar')
            publishArtifacts = true

            // Properties to be attached to the published artifacts.
            properties = ['qa.level': 'basic', 'dev.team': 'core']
            // Publish generated POM files to Artifactory (true by default)
            // POM 檔案
            publishPom = true
        }
    }
}複製程式碼

還有是配置上傳的版本資訊

def MAVEN_LOCAL_PATH ='http://192.168.111.11:8081/artifactory'
def ARTIFACT_ID = 'testsdk'
def VERSION_NAME = '3.0.0'
def GROUP_ID = 'cn.test.test'

publishing {
    publications {
        aar(MavenPublication) {
            groupId GROUP_ID
            version = VERSION_NAME
            artifactId ARTIFACT_ID

            // Tell maven to prepare the generated "*.aar" file for publishing
            artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")

        }
    }
}複製程式碼

最主要的是配置這兩個 task。
然後開始執行上傳!
步驟如下

  • clean 初始化
  • assembleRelease 構建 aar
  • artifactoryPublish 釋出到 Artifactory 中

問題
這裡第一次 publish 的時候上傳失敗,遇到問題,說找不到 POM 檔案。
我去對應的路徑裡面找,確實沒有生成。
一開始我的操作是把上面的 artifactory 中的 defaults 的 publishPom 設定為 false 。這樣能順利 build 的,但是沒有上傳 POM 檔案。

導致了後面在 demo 中通過 compile 'cn.test.test:testsdk:3.0.0' 這樣的形式找不到包,必須通過明確的 aar 字尾的 complie 方式才能找到包,估計 POM 檔案是起到型別配置的作用的。

正確的操作應該執行一下 artifactoryPublish 下面的 generatePomFileForAarPublication 就會生成了。
? 呵呵 沒想到吧
反正我是翻了大量的資料,最後自己發現的。。。看的懂英文多重要!

上傳上去需要配置的三個引數

  • ARTIFACT_ID 你的庫名字
  • GROUP_ID 庫的包名【可以這麼理解】
  • VERSION_NAME 庫的版本號

Lib 的整合

當上一步的包上傳完成之後,在你的本地通過下面兩個配置就可以測試了。
首先在 Demo 的專案 gradle 增加 maven 庫的地址,記得和你上面的對應。
大概是這樣

allprojects {
    repositories {
        jcenter()
        maven { url "http://192.168.111.11:8081/artifactory/gradle-release-local" }
    }
}複製程式碼

在 Demo 的 app 的 gradle dependencies 加上

compile 'cn.test.test:testsdk:3.0.0'複製程式碼

sync 一下你的 gradle 檔案,需要的外掛就下下來了~

注意這個 compile 的格式,是根據這個規則生成的。

GROUP_ID:ARTIFACT_ID:VERSION_NAME複製程式碼

公網對映

上面的流程,你已經可以在你的本地,在連線上伺服器之後,可以愉快的進行構建的,可是目標是為了服務 CP,CP 可不在內網環境。
我們希望的最終目標是他們能配置下面的 repo 地址,就能夠下載到需要的依賴包。

 maven { url "http://repo.test.com/gradle/" }複製程式碼

這邊有兩部分操作

  • Nginx 做埠轉發80到8081
  • 聯絡運維做外網的域名對映

之前一直對 Nginx 是個什麼東西半知半解。
比如我們訪問了一個 tan 90 的網址,看到這個介面

下面一行小字 nginx 。我所理解的 Nginx 應該是客戶端和服務端中間的一層代理,他可以控制 a1 事件到 b 伺服器處理,a2 事件到 c 伺服器處理。請教了後臺的同事,nginx 還有很多作用,如負載均衡等等。

所以我們的流程如下

配置 Nginx

可以參考這篇文章相當的詳細
www.nginx.cn/install

需要以下環境

對應的最新包地址如下,都可以通過 wget 命令下載:

wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.37.tar.gz 
wget http://zlib.net/zlib-1.2.11.tar.gz
wget https://www.openssl.org/source/openssl-1.0.2l.tar.gz複製程式碼

下完之後就是解壓,tar,cd 進去,./config,make,make install 的操作了。
把三個都執行完之後,開始安裝 Nginx 。

最新地址

wget http://nginx.org/download/nginx-1.12.0.tar.gz複製程式碼

這裡要設定一下 configure 的相關引數,設定為上面的幾個包。
預設都是下載到一個路徑下面,解壓安裝

./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid  --with-http_ssl_module --with-pcre=../pcre-8.40 --with-zlib=../zlib-1.2.11 --with-openssl=/usr/local/src/openssl-1.0.2l複製程式碼

啟動 Nginx

通過 /usr/local/nginx/sbin/nginx

發現報錯了:
error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
經網上查詢,這是linux的通病
下面這樣可以解決

[root@localhost nginx]# sbin/nginx 
sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
[root@localhost nginx]# error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
[root@localhost nginx]# whereis libpcre.so.1
libpcre.so: /lib64/libpcre.so.0 /usr/local/lib/libpcre.so /usr/local/lib/libpcre.so.1
[root@localhost nginx]# ln -s /usr/local/lib/libpcre.so.1 /lib64
[root@localhost nginx]# sbin/nginx複製程式碼

先找到libpcre.so.1所在位置,然後做個軟連結就可以了。

再次啟動!
直接訪問你的 ip 地址如果是這個介面就是成功了。

埠轉發

下面就可以,配置 nginx 進行埠的跳轉 80 交給 http://192.168.111.11:8081/artifactory/gradle-release-local。
修改 nginx 的 nginx.conf 檔案。
配置如下

  server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        //通過這裡加了代理的跳轉
        location /gradle/{
            proxy_pass  http://192.168.111.11:8081/artifactory/gradle-release-local/;
        }

    }複製程式碼

這裡用到了重啟 nginx 的指令

./nginx -s reload複製程式碼

通過上面的配置就能實現跳轉功能。
測試的方式就是訪問
http://192.168.111.11/gradle/
看看是不是和之前是一樣的路徑,成功就是說明轉發成功了。

對映

接下來就是聯絡運維幫你做一下外網的對映。就可以通過
repo.test.com/gradle/
來訪問你的 maven 庫了。

總結

通過這篇文章,基本可以從零服務端基礎完整的搭建起一個 maven 倉庫了。如果只是內網或者本地倉庫的話,就不用 nginx 這部分操作了。

相關文章