基於 Node.js 的服務器自動化部署搭建實錄

基於 Node.js 的服務器自動化部署搭建實錄

摘要:本文主要記錄我在服務器上使用 GitHub 的 Webhooks 進行網站自動化部署的過程。最終效果:開發終端向 Github 倉庫推送代碼後,服務器端自動拉取倉庫並重啓服務器。搭建過程主要參考了 lovelucy.info 的博客。html

搭建環境:我正在使用的是 Vultr 的服務器,系統版本是 CentOS 7 x64。node

在服務器上安裝 Node.js

最簡單的方法:從 EPEL 庫安裝 Node.jslinux

$ sudo yum install epel-release
$ sudo yum install nodejs
// 檢查是否成功安裝
$ node --version
$ npm --version

(注:未經本人測試,版本可能相對較老。)git

我我的搭建過程當中使用了 Node.js 官網 的 Linux 二進制文件來安裝 Node.js。下載安裝包時要留意 Linux 的版本。(X86/X64)github

// Node.js 安裝目錄
$ cd /usr/local/bin 

// Node.js 官網提供的 Linux 二進制文件
$ wget https://nodejs.org/dist/v8.12.0/node-v8.12.0-linux-x64.tar.xz

// 解壓縮
$ tar xvJf node-v8.12.0-linux-x64.tar.xz

// 配置環境變量
$ vi /etc/profile

// 添加如下內容到文件末尾 ====================
export NODE_HOME=/usr/local/bin/nodejs

export PATH=$PATH:$NODE_HOME/bin

export NODE_PATH=$NODE_HOME/lib/node_modules

// 添加以上內容到文件末尾 ====================

// 保存退出後source一下,使其當即生效
$ source /etc/profile 

// 檢查是否安裝成功
$ node -v
$ npm -v

至此,成功在服務器上安裝最新版本的 Node.js。web

編寫拉取倉庫、重啓服務器腳本

一個可供參考的例子:deploy.shnpm

#!/bin/bash

WEB_PATH='/home/nodejs-be-demo'

echo "Start deployment"
cd $WEB_PATH
echo "pulling source code..."
git reset --hard origin/master
git clean -f
git pull
git checkout master
npm install
npm run start
echo "Finished."

配置 Github 倉庫的 Webhook 設置

  1. 在要配置的 Github 的設置頁面找到 Webhooks 選項,點擊「Add webhook」。
  2. 配置 Payload URL(接受 POST 請求的服務器 URL)。
  3. Secret(能夠理解爲配對暗號)。
  4. Content-type 選擇 application/json
  5. 其他默認設置便可。

配置 Node.js 腳本

在配置 Node.js 腳本以前,須要先安裝依賴,這裏用到了一箇中間件github-webhook-handler,以及進程管理服務foreverjson

$ npm install -g github-webhook-handler
$ npm install -g forever

腳本內容以下:deploy.jsbash

var http = require('http')
var createHandler = require('github-webhook-handler')
var handler = createHandler({ path: '/autodeploy', secret: 'mySecret' }) 
// 上面的 secret 保持和 GitHub 後臺設置的一致

function run_cmd(cmd, args, callback) {
var spawn = require('child_process').spawn;
var child = spawn(cmd, args);
var resp = "";

child.stdout.on('data', function(buffer) { resp += buffer.toString(); });
child.stdout.on('end', function() { callback (resp) });
}

http.createServer(function (req, res) {
handler(req, res, function (err) {
    res.statusCode = 404
    res.end('no such location')
})
}).listen(7777)
// 這裏是監聽的端口號

handler.on('error', function (err) {
console.error('Error:', err.message)
})

handler.on('push', function (event) {
console.log('Received a push event for %s to %s',
    event.payload.repository.name,
    event.payload.ref);
run_cmd('sh', ['./deploy.sh'], function(text){ console.log(text) });
})

/*
handler.on('issues', function (event) {
console.log('Received an issue event for % action=%s: #%d %s',
    event.payload.repository.name,
    event.payload.action,
    event.payload.issue.number,
    event.payload.issue.title)
})
*/

這裏 Node.js 監聽的是 7777 端口,你也可使用 Nginx 反向代理到 80 端口。服務器

用下面的命令測試一下,接收到 push 以後控制檯會有輸出:

$ node deploy.js

若是沒什麼問題,forever 就能夠開起來了。

$ forever start deploy.js

其餘問題

部署過程當中可能遇到沒法訪問對應端口的問題,須要檢查一下服務器的防火牆設置。大部分服務器都是白名單機制,只開放特定的端口。

CentOS 7 下默認使用的防火牆是 FirewallD,以前版本請搜索iptables
另:FirewallD 和 iptables 的區別?

FirewallD 相關命令:

  • 啓動服務,並在系統引導式啓動該服務

    sudo systemctl start firewalld
     sudo systemctl enable firewalld
  • 中止並禁用

    sudo systemctl stop firewalld
     sudo systemctl disable firewalld
  • 檢查防火牆狀態。輸出應該是 running 或者 not running。

    sudo firewall-cmd --state
  • 容許或拒絕任意端口/協議(如:12345端口,該規則在 public 區域)

    sudo firewall-cmd --zone=public --add-port=12345/tcp --permanent
     sudo firewall-cmd --zone=public --remove-port=12345/tcp --permanent
  • 從新加載 FirewallD 使規則當即生效

    sudo firewall-cmd --reload
  • 查看特定區域的全部配置

    sudo firewall-cmd --zone=public --list-all

    示例輸出:

    public (default, active)
         interfaces: ens160
         sources:
         services: dhcpv6-client http ssh
         ports: 12345/tcp
         masquerade: no
         forward-ports:
         icmp-blocks:
         rich rules:

更多詳細的 FirewallD 配置,請看 CentOS 上的 FirewallD 簡明指南

相關文章
相關標籤/搜索