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


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

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

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

在服務器上安裝 Node.js

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

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

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

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

// 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。

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

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

#!/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 ,以及進程管理服務 forever

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

腳本內容如下:deploy.js

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 簡明指南


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM