GitHub Webhook远程服务器自动部署杂记

也来试试GitHub的自动部署?

GitHub项目仓库配置

在GitHub项目仓库的Settings-Webhooks里,选择Add webhook
填写Payload URL和Secret,保存。

Add Webhook

远程服务器配置

在远程服务器某一位置(如/home/deploy)创建Node.js项目。

首先安装github-webhook-handler包:

1
npm i --save github-webhook-handler

在同一目录下新建一个deploy.js,内容如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var http = require('http')
var createHandler = require('github-webhook-handler')
var handler = createHandler({
path: '/pushCode', // 与GitHub后台设置的Payload URL最后部分一致
secret: '123456' // 与GitHub后台设置的Secret一致
})


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(3000) //远程服务器本地绑定的端口

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) }); //要部署的脚本
})

编写部署脚本(如deploy.sh)。尝试执行

1
sh ./deploy.sh

确认脚本无误。

全局安装forever,启动进程,检查进程列表:

1
2
3
npm i -g forever
forever start /home/deploy/deploy.js
forever list

如果一切正常,输出格式形如:

1
2
data:        uid  command       script       forever pid   id logfile                 uptime                    
data: [0] MHwN /usr/bin/node deploy.js 46226 46293 /root/.forever/MHwN.log 0:0:2:2.253999999999905

附注:常用的forever指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 简单的启动进程
forever start app.js

// 关闭进程
forever stop app.js
forever stop 0 // 关闭指定标号进程,如上述[0]号进程
forever stopall

// 重启进程
forever restart app.js
forever restartall

// 指定forever信息输出文件
forever start -l forever.log app.js

// 指定app.js中的日志信息和错误日志输出文件。
// -o 为console.log输出的信息,
// -e 为console.error输出的信息
forever start -o out.log -e err.log app.js

// 追加日志,forever默认不能覆盖上次的启动日志,
// 如果第二次启动不加-a,则会报错
// -a 等应置于脚本文件名称之前,否则不起作用
forever start -l forever.log -a app.js

// 监听当前文件夹下的所有文件改动
forever start -w app.js

//查看forever进程列表
forever list

附注:SSH对远程服务器localhost端口的映射代理

本地执行:

1
2
# ssh -L {本地映射端口}:{远程端口绑定的ip}:${需要代理的远程端口} {远程ip}
ssh -L 1234:localhost:3000 xxx.xxx.xxx.xxx

输入root密码后,本地的1234端口即可监听远程3000端口的内容。

Nginx 公网映射

1
2
3
4
5
6
7
8
9
10
11
server {
server_name example.com;
...

listen 443 ssl;
...

location /pushCode {
proxy_pass http://127.0.0.1:3000;
}
}

重启Nginx:

1
2
pkill -9 nginx
nginx

如无误,即可访问https://example.com/pushCode,得到deploy.js返回的内容:

1
no such location

最后,尝试git push你的项目仓库,如一切正常,则能在对应的webhook页能找到部署成功的记录,大功告成。

Success