gulp自動化部署:gulp發佈express項目(二)

原文:https://my.oschina.net/songzhu/blog/610337php

1、服務器準備node

    服務器ip地址爲:172.16.70.174git

    1.安裝 Node.jsweb

    參考:http://my.oschina.net/songzhu/blog/608129shell

    2.安裝 PM2express

    PM2 是一個帶有負載均衡功能的 Node 應用的進程管理器。npm

    全局安裝 PM2json

$ npm install pm2 -g
$ pm2 list
[PM2] Spawning PM2 daemon
[PM2] PM2 Successfully daemonized
┌──────────┬────┬──────┬─────┬────────┬─────────┬────────┬────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │
└──────────┴────┴──────┴─────┴────────┴─────────┴────────┴────────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app

    安裝 PM2 若是出現錯誤,大概是網絡和權限問題致使的。仔細看一下錯誤提示,若是是網絡問題,那麼多重試幾回應該就能夠了。gulp

    3.準備發佈目錄    瀏覽器

    /home/admin/publish/web/express-demo

$ cd ~
$ mkdir publish && cd publish
$ mkdir web && cd web
$ mkdir express-demo && cd express-demo
$ pwd
/home/admin/publish/web/express-demo

 

2、建立 PM2  啓動腳本

    進入 express-demo 目錄,添加文件 pm2-start.json

$ touch pm2-start.json

 

    添加如下內容:

[
    {
        "name"        : "express-demo",
        "script"      : "./app.js",
        "watch"       : false,
        "instances"   : "4",
        "exec_mode"   : "cluster_mode",
        "env": {
            "NODE_ENV": "production"
        },
        "out_file": "./logs/app.log",
        "error_file": "./logs/err.log",
    }
]

 

    經過 pm2 start pm2-start.json,可啓動 express-demo。

    更詳細的配置:http://pm2.keymetrics.io/docs/usage/application-declaration/

3、建立 Gulp 任務

    Gulp 用自動化構建工具加強你的工做流程。

    1.全局安裝 gulp

$ npm install gulp -g
$ gulp -v
[23:57:39] CLI version 3.9.0

 

    2.做爲項目的開發依賴安裝 gulp

$ npm install --save-dev gulp
$ gulp -v
[23:58:00] CLI version 3.9.0
[23:58:00] Local version 3.9.0

 

    3.在項目根目錄建立 gulpfile.js

$ touch gulpfile.js
$ gulp
[23:57:01] Using gulpfile ~/demos/express-demo/gulpfile.js
[23:57:02] Task 'default' is not in your gulpfile
[23:57:02] Please check the documentation for proper gulpfile formatting

 

    看到錯誤是由於我沒尚未在 gulpfile.js裏面添加內容

    4.添加 gulp 部署依賴

$ npm install --save-dev gulp-util gulp-shell gulp-ssh gulp-zip through2 scp2 async progress

 

    gulp-util

    gulp-shell

    gulp-ssh

    gulp-zip

    through2

    scp2

    async

    progress

    5.在項目根目錄建立 deploy-ssh.js

$ touch deploy-ssh.js

 

    添加如下內容:

var gulp = require('gulp');
var gutil = require('gulp-util');
var through = require('through2');
var ScpClient = require('scp2').Client;
var ssh = require('gulp-ssh');
var async = require('async');
var ProgressBar = require('progress');

const PLUGIN_NAME = 'deploy-ssh'

module.exports = function (options) {
    var servers = options.servers;
    var dest = options.dest;
    var shell = options.shell;
    var logPath = options.logPath;

    return through.obj(function (file, enc, callback) {
        if (file.isNull()) {
            callback(null, file);
            return;
        }

        if (file.isStream()) {
            return callback(new gutil.PluginError(PLUGIN_NAME, 'No stream support'));
        }

        var i = 0;
        async.eachSeries(servers, function(server, done) {
            var hostName = server.sshConfig.host;
            gutil.log(PLUGIN_NAME, "start deploy:" + hostName)
            var client = new ScpClient(server.sshConfig);

            var bar = null;
            client.on("transfer",  function(buffer, uploaded, total){
                if(bar == null){
                    bar = new ProgressBar(hostName + ' uploading [:bar] :percent :elapsed s', {
                        complete: '=',
                        incomplete: ' ',
                        width: 50,
                        total: total
                    });
                }
                bar.tick(1);
            });
            
            client.write({
                destination: dest,
                content: file.contents
            }, function () {
                ssh(server).shell(shell, {filePath: logPath + "-" + hostName + ".log", autoExit: true}).on('error', function (err) {
                    done(err);

                    gutil.PluginError(PLUGIN_NAME,  err)
                }).on('finish', function () {
                    gutil.log(PLUGIN_NAME, "finish deploy:" + hostName);

                    done();

                    if (++i === servers.length) {
                        callback(null, file);
                    }
                }).pipe(gulp.dest('logs'));
            });
        });

    });

};

 

 

    deploy-ssh 主要用於上傳發布包至服務器並登陸服務器之行發佈腳本。

    6.在項目根目錄建立 deploy-config.js 

$ touch deploy-config.js

 

    添加如下內容:

var config = {
    production:{
        servers:[
        {
            sshConfig: {
                host: '172.16.70.174',
                port: 22,
                username: 'admin',
                password: 'cavin@123',
                readyTimeout: 200000
            }
        }]
    }
};

module.exports = config;

 

 

    deploy-config 主要用於配置deploy服務器信息。

    7.修改 gulpfile.js

     添加如下內容:

var gulp = require('gulp');
var shell = require('gulp-shell');
var ssh = require('gulp-ssh');
var deployConfig = require("./deploy-config");
var gulpSequence = require('gulp-sequence');
var zip = require('gulp-zip');
var through = require('through2');
var async = require('async');
var scpClient = require('scp2');
var gulpUtil = require('gulp-util');
var deploySSH = require('./deploy-ssh');

const PLUGIN_NAME = 'gulp-deploy ::'

gulp.task('default', shell.task([
  'DEBUG=express-demo:* npm start'
]));

gulp.task('production', function (){
   shell.task(['rm -rf dist']);
   gulpSequence('copyFile', 'zipFile', 'deploy',  function() {
       gulpUtil.log(PLUGIN_NAME, "***** Deploy Finished!!!!");
       process.exit(0);
    });
});

gulp.task('copyFile', function() {
    return gulp.src(
            [
                '*.json',
                '*.js',
                'routes/**',
                'views/**',
                'public/**',
                '!config.js'
            ], { base: './'})
            .pipe(gulp.dest('./dist'));
});

gulp.task('zipFile', function() {
    return gulp.src(['dist/**'], { base: './' })
            .pipe(zip('publish.zip'))
            .pipe(gulp.dest('./dist'));
});

gulp.task('deploy', function() {
    var config = deployConfig.production;
    config.deployPath = '/home/admin/publish/web/express-demo/';
    return gulp.src("dist/publish.zip", { base: './' })
            .pipe(deploySSH({
                servers: config.servers,
                dest: config.deployPath + 'publish.zip',
                logPath: 'deploy',
                shell:[ 'cd ' + config.deployPath,
                        'shopt -s extglob',
                        'rm -rf !(logs|node_modules|config.js|publish.zip)',
                        'unzip -o publish.zip',
                        'cp -rf dist/** .',
                        'rm -rf dist',
                        "rm publish.zip",
                        'npm install --production',
                        'pm2 startOrRestart pm2-start.json'],
            }));
});

 

    主要 gulp 任務流程爲:

        1)拷貝文檔至臨時目錄

        2)壓縮文件

        3)發佈(先上發佈包,而後遠程登陸服務器之行發佈腳本)

    注:發佈目錄 '/home/admin/publish/web/express-demo/' 必定要存在,不然scp上傳文件時會出錯。

4、一鍵部署 express-demo    

    執行發佈任務

 $ gulp production

    若是沒有錯誤,登陸服務器上面能夠看到:

$ pm2 list
┌──────────────┬────┬─────────┬──────┬────────┬─────────┬────────┬─────────────┬──────────┐
│ App name     │ id │ mode    │ pid  │ status │ restart │ uptime │ memory      │ watching │
├──────────────┼────┼─────────┼──────┼────────┼─────────┼────────┼─────────────┼──────────┤
│ express-demo │ 0  │ cluster │ 2537 │ online │ 0       │ 102s   │ 30.117 MB   │ disabled │
│ express-demo │ 1  │ cluster │ 2542 │ online │ 0       │ 102s   │ 30.133 MB   │ disabled │
│ express-demo │ 2  │ cluster │ 2543 │ online │ 0       │ 102s   │ 30.109 MB   │ disabled │
│ express-demo │ 3  │ cluster │ 2544 │ online │ 0       │ 102s   │ 30.363 MB   │ disabled │
└──────────────┴────┴─────────┴──────┴────────┴─────────┴────────┴─────────────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app

 

    在瀏覽器裏面輸入:http://172.16.70.174:3000/

 

項目代碼:https://git.oschina.net/cavintang/express-demo.git

相關文章
相關標籤/搜索