Create a simple deployment system based on webhook


Installing nodejs

To install nodejs, it is recommended to download the binary package directly and copy the 64 bit binary version download address on the official website for execution


xzUnzip the file in the following command:

  1. xz -d xxx.tar.xzAdd XXX tar. Unzip XZ into XXX tar

  2. tar xvf xxx.tarCome and unpack

After decompression, copy the directory to/usr/local/nodeUnder the directory

cp ~/node_v**** /usr/local/node

To facilitate global startup, you need to/usr/local/binCreate file soft connection under

ln -s /usr/local/node/bin/npm /usr/local/bin

ln -s /usr/local/node/bin/node /usr/local/bin

After execution, it can be used globallynpmandnodeOrders.

Due to network problems, Alibaba NPM image can be used in Chinacnpm

npm install -g cnpm --registry=

Then usually/usr/binThe following are the pre installed executable programs of the system, which will change with the system upgrade/usr/local/binDirectory is a place where users can place their own executable programs. It is recommended to put them here. Files with the same name will not be overwritten by system upgrade If there are the same executable programs in two directories, who will be the first to execute themPATHInfluence of environmental variables

Write webhook code

Deployment script

Here, we want to start the shell script after remote HTTP call, so we write the deployment script first. Because the configuration files of my development environment and test environment are different, the GIT directory and deployment directory are separated. Between two directoriesUnidirectional synchronization, the scheme I adopt here isrsync, thoughdiffFolder comparison can also be realized, but the synchronization process is complex and manual analysis of directory changes is required.

The framework of this project islaravelxxx_gitIs the source directory,xxxIt is the deployment directory, which can be adjusted according to the specific situation.

Here we usersyncOne way synchronization, single filecpDirect coverage.

cd /home/wwwroot/xxx_git
git pull origin master
cp /home/wwwroot/xxx_git/composer.json /home/wwwroot/xxx/composer.json
cp /home/wwwroot/xxx_git/composer.lock /home/wwwroot/xxx/composer.lock
cp /home/wwwroot/xxx_git/_ide_helper.php /home/wwwroot/xxx/_ide_helper.php
rsync --delete -avzp /home/wwwroot/xxx_git/app /home/wwwroot/xxx/
rsync --delete -avzp /home/wwwroot/xxx_git/public /home/wwwroot/xxx/
rsync --delete -avzp /home/wwwroot/xxx_git/resources/lang /home/wwwroot/xxx/resources
rsync --delete -avzp /home/wwwroot/xxx_git/resources/views /home/wwwroot/xxx/resources

After the script is written, execute the following commands to give execution ability

chmod +x ./

Rsync parameter:
-a: indicates the archive mode and transfers files recursively
-v: detailed output
-zFile compression during transfer:
-r: recursion of subdirectories
-t: keep the time information of the file
-p: keep file permissions
-o: keep the ownership information of the file
-g: keep the group information of the file
--delete: means to synchronize based on the server and keep the directory file of the server completely consistent with that of the client
--progress: used to display the process of data synchronization
--exclude: exclude directories or files that do not need to be synchronized

Webhook interface writing

Here I use webhoos above gitos, and other gitlab and GitHub are similar.
The webcook of oschina is visiblehere

Here I useexpress + child_processTo solve the call problem, the process is relatively simple. What we need to pay attention to is to detect the submissionpushDid you operate itmasterThe other two parts are submitted so that they will not be processed.

hereexecandreq.send()There is no callback relationship, so the server webhook will not timeout. In addition, it also realizes the logging of script operation, which can view the specific file changes for each deployment.

var express = require('express');
var app = express();
var cp = require('child_process');
var bodyParser = require('body-parser');
var jsonParser = bodyParser.json();
var moment = require('moment');'/git' , jsonParser ,function(req , res){
    var json = req.body;
    if(json.password == 'xxxx'){
        if (json.ref == 'refs/heads/master'){
            var logName = (moment().format('YYYY-MM-DD_HH:m:s'))+'.log';
            var command = '/home/nodejs/git_puber/ >> /home/nodejs/git_puber/' + logName;
            cp.exec(command, function(err, out, code) {
              if (err instanceof Error) {
                // res.writeHead(500)
                // res.end('Server Internal Error.')
                // throw err
                console.log(err + new Date());
                console.log(out + new Date());
            console.log('not master branch');
        console.log('no auth pass');
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.send({result:('ok' + new Date()) , msg: 'your message has been delievered'});
    // res.send();

app.listen(3000 , function(){
    console.log('Server Is Running' + new Date());

Reference extension
Differences and pitfalls between exec and spawn methods

Operation monitoring program

Nodejs is an asynchronous single thread. In some cases, there will be abnormal exit. In order to ensure that the service is often available, we need apm2To ensure the operation of the program.

npm install pm2 -g

It can be used if the installation speed is slowcnpmInstallation.

implementpm2 start node app.jsThat is, the node program can be maintained and run in the background.

PM2 some commands
pm2 list
pm2 stop all/[name]
pm2 start all/[name]

Automatic deployment

git checkout dev

Modify the file after switching to the dev branch

git commit

Switch to the main branch and merge the dev halves

git checkout dev && git merge dev

Automatic server deployment after submission

git push