在之前的文章裡我講到了自己最近日子裡與自動部署這件事的愛恨情仇,最後由於github太卡,但又抵抗不了牆的存在,最後更改了自己專案分享和部署的方案。
在之前的日子裡,我的全部專案都在github裡,需要分享的就設定為public,只是部署使用的就用private。變更方案後,github只用作程式碼分享,因為它畢竟是一個社交網站。用作部署的程式碼轉移到碼雲。再在自己的伺服器上搭建一個jenkins用於自動部署。
jenkins是一個開源的ci/cd工具,可以用於專案的自動部署。它還有很多其他作用,但我沒用上。
jenkins的中文文件是:Jenkins 使用者手冊 。
環境準備
由於是在自己的伺服器上搭建,所以下面一切的描述均基於CentOS7作業系統,執行於阿里雲的ECS T5雲主機。
參考jenkins使用者指南,我們知道jenkins需要
- 機器要求:
- 256 MB 記憶體,建議大於 512 MB
- 10 GB 的硬碟空間(用於 Jenkins 和 Docker 映象)
- 需要安裝以下軟體:
- Java 8 ( JRE 或者 JDK 都可以)
- Docker (導航到網站頂部的Get Docker連結以訪問適合您平臺的Docker下載)
安裝Java8
這部分參考Linux下透過yum命令安裝jdk8。
檢視已安裝/解除安裝
先檢視有沒有已經安裝java8。
# rpm -qa | grep java
javapackages-tools-3.4.1-11.el7.noarch
python-javapackages-3.4.1-11.el7.noarch
java-1.8.0-openjdk-headless-1.8.0.242.b08-0.el7_7.x86_64
tzdata-java-2019c-1.el7.noarch
java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64
由於我已經安裝,所以會顯示一系列名字裡帶有java的包。如果已經安裝其他版本的java jdk,使用
# rpm -e --allmatches --nodeps java-1.6.0-openjdk-1.6.0.38-1.13.10.4.el6.x86_64
解除安裝。
查詢jdk8包
# yum search jdk
已載入外掛:fastestmirror
Loading mirror speeds from cached hostfile
* epel: mirrors.yun-idc.com
* webtatic: uk.repo.webtatic.com
======================================================== N/S matched: jdk ========================================================
copy-jdk-configs.noarch : JDKs configuration files copier
java-1.6.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.6.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.6.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.6.0-openjdk-javadoc.x86_64 : OpenJDK API Documentation
java-1.6.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.7.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.7.0-openjdk-accessibility.x86_64 : OpenJDK accessibility connector
java-1.7.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.7.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.7.0-openjdk-headless.x86_64 : The OpenJDK runtime environment without audio and video support
java-1.7.0-openjdk-javadoc.noarch : OpenJDK API Documentation
java-1.7.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.8.0-openjdk.i686 : OpenJDK Runtime Environment 8
java-1.8.0-openjdk.x86_64 : OpenJDK Runtime Environment 8
java-1.8.0-openjdk-accessibility.i686 : OpenJDK accessibility connector
java-1.8.0-openjdk-accessibility.x86_64 : OpenJDK accessibility connector
java-1.8.0-openjdk-accessibility-debug.i686 : OpenJDK 8 accessibility connector for packages with debug on
java-1.8.0-openjdk-accessibility-debug.x86_64 : OpenJDK 8 accessibility connector for packages with debug on
java-1.8.0-openjdk-debug.i686 : OpenJDK Runtime Environment 8 with full debug on
java-1.8.0-openjdk-debug.x86_64 : OpenJDK Runtime Environment 8 with full debug on
java-1.8.0-openjdk-demo.i686 : OpenJDK Demos 8
java-1.8.0-openjdk-demo.x86_64 : OpenJDK Demos 8
java-1.8.0-openjdk-demo-debug.i686 : OpenJDK Demos 8 with full debug on
java-1.8.0-openjdk-demo-debug.x86_64 : OpenJDK Demos 8 with full debug on
java-1.8.0-openjdk-devel.i686 : OpenJDK Development Environment 8
java-1.8.0-openjdk-devel.x86_64 : OpenJDK Development Environment 8
java-1.8.0-openjdk-devel-debug.i686 : OpenJDK Development Environment 8 with full debug on
java-1.8.0-openjdk-devel-debug.x86_64 : OpenJDK Development Environment 8 with full debug on
java-1.8.0-openjdk-headless.i686 : OpenJDK Headless Runtime Environment 8
java-1.8.0-openjdk-headless.x86_64 : OpenJDK Headless Runtime Environment 8
java-1.8.0-openjdk-headless-debug.i686 : OpenJDK Runtime Environment with full debug on
java-1.8.0-openjdk-headless-debug.x86_64 : OpenJDK Runtime Environment with full debug on
java-1.8.0-openjdk-javadoc.noarch : OpenJDK 8 API documentation
java-1.8.0-openjdk-javadoc-debug.noarch : OpenJDK 8 API documentation for packages with debug on
java-1.8.0-openjdk-javadoc-zip.noarch : OpenJDK 8 API documentation compressed in a single archive
java-1.8.0-openjdk-javadoc-zip-debug.noarch : OpenJDK 8 API documentation compressed in a single archive for packages with debug
: on
java-1.8.0-openjdk-src.i686 : OpenJDK Source Bundle 8
java-1.8.0-openjdk-src.x86_64 : OpenJDK Source Bundle 8
java-1.8.0-openjdk-src-debug.i686 : OpenJDK Source Bundle 8 for packages with debug on
java-1.8.0-openjdk-src-debug.x86_64 : OpenJDK Source Bundle 8 for packages with debug on
...
名稱和簡介匹配 only,使用“search all”試試。
安裝
在輸出的包名中找到需要的java8安裝包,執行命令
# yum install java-1.8.0-openjdk.x86_64
進行安裝。
安裝過程中會同時安裝依賴項。
安裝成功後,使用
# java -version
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-b08)
OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)
檢測是否已經安裝成功。
安裝成功後,就可以在後面使用java
命令了。
安裝docker
就沒啥好解釋的,直接
# yum install docker
安裝就完事了。
下載jenkins
官方文件給的連結是mirrors.jenkins.io/war-stable/lates...,我們這裡可以使用清華大學開源映象站-jenkins,使用wget
下載最新的映象。
# wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.231/jenkins.war
啟動jenkins
cd
到下載目錄下,使用命令
# java -jar jenkins.war --httpPort=8080
來啟動jenkins。
如果8080埠被佔用了,可以使用任何其他未佔用介面。如果安裝了防火牆,則需要將埠加到防火牆白名單裡。如果像我一樣用了雲主機,則需要在安全組配置允許此埠通行。
啟動成功後,在瀏覽器訪問http://ip:8080,按照引導進行安裝。
啟動jenkins安裝程式的時候會在控制檯顯示一個密碼,在第一步會用到。
如果控制檯沒有顯示,可以使用cat
命令檢視介面上顯示的檔案。
下一步選擇外掛。
選擇第二個,然後搜尋Chinese,安裝一箇中文外掛就行。其他安裝起來太慢,也沒啥用。
下一步建立使用者,完事就能進jenkins的介面了。
現在有一個問題,命令列那邊還等著呢,我們關閉了控制檯就沒法用了啊。
使用守護程式方式啟動jenkins
參考了這篇文章,首先使用yum安裝daemonize。
# yum install daemonize
daemonize
的使用方法是
daemonize -E BUILD_ID=dontKillMe -o some.log -c /home/User/victor /home/User/victor/test.sh
-E BUILD_ID=dontKillMe
是這次執行的id,可以隨便寫一個。
-o some.log
是這次執行的日誌檔案。
-c /home/User/victor
是執行前要切換的目錄。
/home/User/victor/test.sh
是要啟動的指令碼。
於是我們前往一個特殊目錄cd /usr/local/bin && mkdir jenkins
,編寫一個指令碼,用來啟動jenkins。
# vim jenkins_daemonize.sh
#!/bin/bash
java -jar /usr/local/bin/jenkins/jenkins.war --httpPort=8081
<esc>
:eq
再編寫另一個指令碼,使用daemonize
執行上一個指令碼。
# vim jenkins_start.sh
#!/bin/bash
daemonize -E BUILD_ID=dontKillMe -o jenkins.log -c /usr/local/bin/jenkins "/usr/local/bin/jenkins/jenkins_daemonize.sh"
<esc>
:eq
為啥要寫倆指令碼呢,因為daemonize
最後一個引數接受的就是sh指令碼啊。
再建立一個日誌檔案。
# touch jenkins.log
修改指令碼檔案和日誌檔案的許可權。
# chmod +x jenkins_daemonize.sh
# chmod +x jenkins_start.sh
# chmod 777 jenkins.log
然後執行指令碼jenkins_start.sh
,jenkins就以守護程式的方式啟動了。
# ./jenkins_start.sh
我們可以使用ps
命令檢視執行情況。
# ps -ef | grep jenkins
root 15735 13474 0 21:01 pts/0 00:00:00 grep --color=auto jenkins
root 30515 1 0 4月14 ? 00:00:00 /bin/bash /usr/local/bin/jenkins/jenkins_daemonize.sh
root 30516 30515 0 4月14 ? 00:03:58 java -jar /usr/local/bin/jenkins/jenkins.war --httpPort=8081
配置nginx反向代理
用daemonize
啟動成功後,服務啟動在http://127.0.0.1:8081上,這時候我們需要配置nginx代理,從而可以使用域名訪問。
server {
listen 80;
server_name jenkins.xtzero.me;
location / {
proxy_pass http://127.0.0.1:8081;
}
}
儲存後重新載入nginx配置。
# nginx -s reload
在瀏覽器中訪問http://jenkins.xtzero.me,即可看到啟動好的jenkins。
jenkins與gitee聯動
先將程式碼傳到gitee,同一個專案下的不同子專案使用分支實現,例如我的部落格分為life、tech、api,在倉庫裡新建三個分支。
聯動的思路是,在jenkins裡配置好構建指令碼,gitee push成功時告訴jenkins倉庫名和分支名,jenkins分別進行構建。構建的過程就是在伺服器上拉取程式碼,執行安裝、構建,再將生成好的資源複製到網頁目錄。
下面將用我的blog專案進行說明。
需要解釋的是,jenkins有gitee外掛,可以像runner那樣來進行自動部署。由於我的需求特殊,也有更省事(或許是我更能理解的方式)來解決,所以我決定走自己的路線。
配置jenkins 流水線
點選jenkins首頁的新建item,任務名稱為“倉庫名_分支名”,任務型別選擇criswu擅長的freestyle。
進入任務配置,勾選觸發遠端構建
在最下方選擇增加構建步驟,選擇shell方式
新增指令碼進去
rm -rf blog_tech
git clone -b tech git@gitee.com:xtzero/blog.git blog_tech
cd blog_tech
yarn install
hexo g
rm -rf /data/www/blog/tech
cp -R ../blog_tech /data/www/blog/tech
我的部落格是用hexo搭建的,所以會進行上面的步驟。
jenkins的原理是,在~/.jenkins/workspace
目錄下會為每一個專案建立一個單獨的目錄。為了避免重複,在git clone的時候我們依然使用“倉庫名_分支名”的形式。
clone專案後,執行安裝、構建。構建出靜態資源後,刪除網站目錄的舊版檔案,把構建好的靜態資源複製進去。一次流水線結束。
由於勾選了遠端構建,所以我們需要在gitee push成功的時候傳送訊息到jenkins。這時候就需要伺服器上有一個介面指令碼來接受push訊息,再請求jenkins的遠端構建介面。
指令碼使用php編寫。
<?php
require_once 'curl.php';
$avaliableRepoBranch = [
'blog_tech',
'blog_life',
'blog_api',
'xtCBook_master',
'brown-and-cony_master'
];
$postData = file_get_contents('php://input');
$d = json_decode($postData, true);
$refArr = explode('/', $d['ref']);
$branchName = $refArr[count($refArr) - 1];
$repoName = $d['repository']['name'];
$repoAndBranch = implode('_', [$repoName, $branchName]);
if (in_array($repoAndBranch, $avaliableRepoBranch)) {
echo '訪問了http://jenkins.xtzero.me/job/'.$repoAndBranch.'/build?token=jenkins';
echo curlGet('http://jenkins.xtzero.me/job/'.$repoAndBranch.'/build?token=jenkins');
} else {
echo '不在陣列裡,構建直接他媽結束';
}
編寫好指令碼後,配置nginx解析。
server {
listen 80;
server_name webhook.jenkins.xtzero.me;
location ~ \.php$ {
root /data/www/forJenkins;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}
jenkins遠端構建地址的特點是http://jenkins地址/job/任務名稱/build?token=TOKEN
,由於我們的任務名稱是倉庫名和分支名決定的,所以只要在push資訊裡獲取到倉庫名和分支名,就可以請求到對應的jenkins地址了。
前往gitee專案頁面,點選右上角管理,選擇WebHooks,將上一步配置的介面地址填上。
一旦執行了push動作,就會在WebHooks頁面看到請求結果。
前往jenkins頁面,可以看到構建已經開始了。
點進去具體一個構建,點選左側控制檯輸出,可以看到詳細的控制檯輸出資訊。
訪問對應的網站地址,可以看到確實已經構建成功。
配置更多專案
每一個專案的構建流程都不盡相同,所以需要對每一個專案配置不同的構建指令碼。但是思路都大致相同,都是clone專案、安裝、構建、複製到網站目錄。
依次配置好需要構建的專案,就可以開始快樂寫程式碼了。
完事
就完事了。
本作品採用《CC 協議》,轉載必須註明作者和本文連結