GitLab+Jenkins+Rsync+PM2實現Node項目的持續集成與自動部署

前言

最原始的軟件開發流程是,在本地搭建好環境,進行開發測試,而後去服務器上搭建環境,手動上傳代碼,運行測試,而後啓動服務。實際上,近些年來出現了不少的工具,使得這些步驟能夠自動化,大大下降人工出錯的機率,提升生產效率。下面,我就把GitLab+Jenkins+Rsync+PM2實現的Node項目的持續集成以及自動部署的實驗過程記錄下來。java

搭建環境

須要兩臺服務器做爲演示,A主要進行代碼管理、構建和分發,B主要運行實際應用。我這邊系統使用的是Debian系的。node

服務器A

GitLab

準備工做:mysql

apt-get update
apt-get install curl openssh-server ca-certificates postfix

安裝postfix的時候,選internet site,以後的 system mail name 填寫你的服務器的IP地址。linux

準備好後開始安裝:git

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash
apt-get install gitlab-ee

若是 apt 下載很慢能夠手動下載 https://packages.gitlab.com/gitlab/gitlab-ee/packages/ubuntu/trusty/gitlab-ee_10.2.2-ee.0_amd64.deb 而後用 dpkg -i 的方式安裝。裝了這個事後 NGINX, Postgres, Redis 就都裝好了。web

配置:redis

GitLab默認會佔用80、8080和9090端口,Jenkins默認也會使用8080端口,因此將GitLab的默認端口爲60200、6020一、60202(你能夠隨意定製)sql

vim /etc/gitlab/gitlab.rb 修改docker

external_url 'http://<你的服務器ip>:60200'
unicorn['port'] = 60201
prometheus['listen_address'] = 'localhost:60202'

注意不能有多餘空格。gitlab-ctl reconfigure生效配置,gitlab-ctl start啓動。
若是要想發郵件的話還要配置第三方郵件 vim /etc/gitlab/gitlab.rbshell

gitlab_rails['smtp_enable'] = true 
gitlab_rails['smtp_address'] = "smtp.exmail.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "***#**"
gitlab_rails['smtp_password'] = "**************"
gitlab_rails['smtp_domain'] = "qq.com"
gitlab_rails['smtp_authentication'] = :login 
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = "***#**"
user["git_user_email"] = "***#**"

而後生效重啓,打開http://<你的服務器IP>:60200訪問,

Jenkins

準備工做:

wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u151-b12/e758a0de34e24606bca991d704f6dcbf/jdk-8u151-linux-x64.tar.gz"
tar xzvf jdk-8u151-linux-x64.tar.gz -C /usr/local/  
vim /etc/profile #(加入環境變量)
    export JAVA_HOME=/usr/local/jdk1.8.0_151
    export PATH=$JAVA_HOME/bin:$PATH

退出,source /etc/profile 生效,用 java -version 驗證是否裝好java。

開始安裝:

curl -O http://mirrors.jenkins.io/war-stable/latest/jenkins.war 下載Jenkins,
nohup java -jar jenkins.war --httpPort=60203 & 後臺啓動並指定端口。
至此,Jenkins安裝成功,能夠用瀏覽器打開 http://<你的服務器ip>:60203
而後安裝必要的插件(會提示你),依次點擊 「系統管理」 「管理插件」。
切換到「可選插件」,分別搜索「GitLab Plugin」和「Git Plugin」,而後點擊「直接安裝」。若是在「可選插件」裏沒有搜到,可能自帶安裝了

Node

apt-get update
apt-get install -y build-essential curl
curl -sL https://deb.nodesource.com/setup_8.x | bash 
apt-get install -y nodejs
node -v
v8.9.2
npm -v
5.5.1

Rsync

這個服務器主要使用Rsync來發布文件,因此不須要特殊配置,通常Linux都默認安裝了,若是沒有,則使用 apt-get install rsync。而後配置Rsync密碼

echo "123" >> /etc/rsync.password
chmod -R 600 /etc/rsync.password

服務器B

Node

如A

PM2

npm install -g pm2
pm2 -v
2.8.0

Rsync

爲了安全性不要直接使用ssh帳號密碼或者公鑰私鑰,而是構建Rsync服務。vim /etc/rsyncd.conf,修改配置,下面的配置只是一個示例,生產環境還要更安全的策略。

##rsyncd.conf start##
uid = root
gid = root
use chroot = yes
max connections = 200
timeout = 300
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
ignore errors
read only = false
list = false
hosts allow = * 
hosts deny =10.0.8.9
auth users = backuser
secrets file = /etc/rsync.password
[webapp]
path = /var/webapp/

上面的的路徑path不存在則須要建立 mkdir /var/webapp
echo "backuser:123" >> /etc/rsync.password 添加帳號和密碼,密碼要與客戶端(A)一直
chmod -R 600 /etc/rsync.password 修改權限
rsync --daemon 以守護進程方式來啓動rsync服務
chkconfig rsync on 將此服務設置成爲開機自啓動

應用開發

用express開發一個 hello world 做爲演示,在本地工程目錄

npm init #(按照提示輸入參數)
npm install express --save  #(安裝express)

而後建立app.js

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});

node app.js 運行,而後http://localhost:3000/ 會獲得 hello world

新建app.json

{
    "apps" : [
        {
            "name"        : "app",
            "script"      : "app.js",
            "log_date_format"  : "YYYY-MM-DD HH:mm:SS",
            "env": {
                "NODE_ENV": "production"
            },
            "watch" : [
                "app.js",
                "router",
                "util"
            ],
            "ignore_watch" : [
                "logs",
                "node_modules",
                "test"
            ]
        }
    ]
}

將代碼上傳至服務器B,而後 pm2 start app.json 運行 便可在瀏覽器訪問 http://B-ip:3000 獲得 hello world

持續集成和自動部署

配置 Gitlab

首次登錄的密碼是會提示你去服務器找,用戶是root,而後修改你的用戶帳號信息,添加你本身經常使用的電腦上的git公鑰。
建立一個新項目 webapp ,建立好事後項目會顯示該項目對應的用戶信息(會提示你修改)

Git global setup

git config --global user.name "MageekChiu"
git config --global user.email "mageekchiu@mail.**.cn"

在本地項目目錄下,新建 .gitignore 文件(window 要用 命令行 rename才能夠)

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

node_modules/

而後執行

git init
git remote add origin git@A-ip:root/webapp.git
git add .
git commit -m "Initial commit"
git push -u origin master

便可提交服務器倉庫,之後每次修改都要

git add .
git commit -m "修改備註"

配置 jenkins

首先配置GitLab插件:
打開GitLab,點擊「setting」——「Account」,複製「Private token」,或者應該首先生成personal access token。
打開Jenkins,點擊「系統管理」——「系統設置」,點擊「配置」下拉框,點擊「Gitlab」選項配置GitLab
Connection Name 隨便,如 gitlab,「Git Host URL」填GitLab的訪問地址,
而後Credentials點「Add」——「jenkins」,在彈出框裏,「kind」選擇「GitLab API Token」,將先前複製的「Private token」粘貼到「API token」輸入框中,而後點擊「Add」,添加後,Credentials選擇剛剛新建的gitlab,
最後點擊「test connection」,看到「Success」就成功了。而後點擊頁面底下的「apply」,再點擊「save」

而後配置Git插件:
須要注意的是裝Jenkins的機器上必定要裝git: apt-get install git 這樣Jenkins才能去 gitlab 拉取文件。
打開Jenkins,點擊「系統管理」——「系統設置」,點擊「配置」下拉框,選擇「Git plugin」選項,設置Git插件的全局配置,填入上面的 global setting 如 global user.name等,而後點擊「apply」——「save」

生成訪問Gitlab的ssh祕鑰:
打開GitLab,點擊右上角的「setting」—— SSH Keys,就能夠進入到添加界面。
在jenkins所在服務器上生成密鑰

ssh-keygen -t rsa -C "root@<你服務器的ip地址>" -b 4096
ssh-keygen -t rsa -C "root@" -b 4096

所有按 Enter 使用默認值,這會生成一對公鑰和私鑰。打開公鑰複製到gitlab的添加界面,而後點擊「add key」,並記住私鑰的存放路徑。

建立一個Jenkins Job:
直接點新建,「item name」能夠隨便起,而後點擊「構建一個自由風格的軟件項目」,點擊「OK」,至此,建立一個Job成功了。而後配置這個job,選擇「源碼管理」,選擇「Git」,而後去GitLab中複製項目地址,粘貼到「Repository URL」,而後點擊「credentials」後面的「Add」按鈕
在彈出頁面裏面:
● Kind 選擇 SSH Username with private key
● Username 填 root
● PrivateKey 選擇 From a file on jenkins master ,而後將服務器的 私鑰的存放路徑(/root/.ssh/id_rsa ) 粘貼進去
而後點擊「Add」,在「credentials」裏選擇咱們剛剛建立的認證方式。若是沒報錯,說明成功了,點擊頁面底部的「apply」。若是出錯了,會在「Repository URL」和「Credentials」之間顯示紅色的錯誤信息。

選擇 構建觸發器:
選擇 Build when a change is pushed to GitLab. 記住這個 GitLab CI Service URL ,點擊高級
Secret token 那一行下面 點擊 generate。記住這個token
選擇 構建:
選擇 execute shell

npm install 
WEB_SERVER_IP=B的ip
PROJECT=webapp/
rsync -arqz --delete-before $WORKSPACE/ $WEB_SERVER_IP::$PROJECT --exclude ".git" --password-file=/etc/rsync.password

這一段代碼的主要目的是構建,並分發代碼,若是有多個應用服務器就要分發到多個服務器上。

配置gitab的webhook:
點擊webapp 項目下面的setting的integrations 輸入剛纔的 GitLab CI Service URL 和 Secret Token
而後點擊add webhook ,再測試一下選擇 push events 若是顯示Hook executed successfully: HTTP 200 即成功,而後在jenkins裏面查看是有一次構建記錄的。

這樣jenkins就會在代碼發生變化時自動拉取代碼到本地,構建,而後用rsync分發給各個應用服務器,結合PM2的watch功能實現自動發現代碼更新並重啓的功能,達到自動部署的目的

最終效果測試

修改代碼,把hello world改成hello gitlab+enkins而後 add、commit、push 。在A上面gitlab有提交記錄,jenkins有構建記錄,在B上面用 pm2 ls 發現項目是restart了,瀏覽器查看也變成hello gitlab+enkins 了。
嘗試成功!
雖然這個配置比較麻煩,可是持續集成和自動部署的帶來的好處是更大的:代碼有版本管理,能夠快速迭代、快速回滾,同時保持高質量、自動多機部署防止人工錯誤,每次構建都有記錄,構建冪等......

參考

http://blog.csdn.net/ruangong...

原文 mageek

後記

這個過程已經比較自動化了,可是仍是有太多的環境搭建過程,好比webapp通常都會用到mysql、redis、MongoDB等等,一個更自動化的過程應該引入docker,這方面之後有機會再嘗試。

相關文章
相關標籤/搜索