精华 使用shipit-deploy实现自动化的多服务器部署
发布于 1 个月前 作者 danlanxiaohei 1221 次浏览 来自 分享

序: 相信大家都有过部署项目的经验,不过,每个人的部署方式却不尽相同,下面列举两个常见的方式。

  • 直接使用rsync/scp命令拷贝代码,然后登录到对应机器操作一些启动命令
  • 写好一个脚本文件放在服务器上,在脚本中使用git 、pm2之类的命令完成部署,登陆对应服务器执行该脚本

但是这些方式都有一些缺点:

  • 都需要分别登录对应服务器上去操作。如果有个十台八台的,操作的时间成本成倍提高
  • 对于回滚操作支持不好。需要手动维护之前的版本的代码,上线后发现bug,还要一台一台的回滚

那么,有没有更好的部署方式呢?


shipit-deploy 闪亮登场

Set of deployment tasks for Shipit based on git and rsync commands.

目标:

  • 一键部署多台服务器。
  • 一键回滚多台服务器。
  • 本地操作,不需要登录服务器。
  • 方便定制扩展,实现全自动化流程。

一,如何使用

1, shipit-deploy是基于shipit-cli的基础上实现的。所以要安装shipit-cli和shipit-deploy这两个。

npm install --save-dev shipit-cli npm install --save-dev shipit-deploy

2, 和服务器建立信任关系,可以使用ssh-copy-id 3, 在项目根目录下创建shipitfile.js

module.exports = function (shipit) {
  require('shipit-deploy')(shipit);
  shipit.initConfig({
    default: {
      workspace: '/tmp/github-monitor',
      deployTo: '/tmp/deploy_to',
      repositoryUrl: 'https://github.com/user/repo.git',
      ignores: ['.git', 'node_modules'],
      keepReleases: 2,
      deleteOnRollback: false,
      key: '/path/to/key',
      shallowClone: true
    },
    staging: {
      servers: ['[email protected]', '[email protected]'],
      branch: 'master'
    }
  });
};

4, 然后执行下面命令即可一键部署/回滚myserver1和myserver2两台机器上

shipit staging deploy shipit staging rollback

更详细的使用,请移步官网查看。


二,原理

为什么shipit可以做到不用登陆就可以操作远程服务器呢?

这是因为它使用的是ssh命令操作远程服务器,不了解的同学可以在终端敲个命令感受一下:ssh user@remote_host “pwd; ls”。

为什么可以一键部署到多台机器呢?

简单来讲,配置中的每个server都会对应创建一个对象,每执行一个远程命令,会遍历所有的对象去执行。


三,定制扩展

代码已经上传到服务器了,接下来就是要启动项目了,比如我们用pm2来启动,启动前还需要执行npm install来安装项目依赖。那这些流程是否也可以加入到自动化的流程中呢?

当然可以,shipit-deploy的执行过程中会执行一系列任务,每执行完一个任务,都会emit一个事件,只要我们监听这个事件就可以做我们想做的事。接下来我们就定制一个简单的shipit的插件。

index.js

var utils = require('shipit-utils');
module.exports = function (shipit) {
  shipit = utils.getShipit(shipit);
  require('./do_something')(shipit);
  shipit.on('published', function () { // 监听published事件,触发后就执行do_something任务。
    shipit.start('do_something');
  });
};

do_something.js

var utils = require('shipit-utils');
module.exports = function(shipit) {
  utils.registerTask(shipit, 'do_something', task);
  function task() {
    shipit.config = shipit.config || {}; // 读取相关配置
    var cmd = 'cd /path/to/project; npm install --production'; // 你想要执行的命令
    return shipit.remote(cmd); // 当触发do_something后,就会在服务器上执行cmd。
  }
}

插件定制、发布完毕后,在shipitfile.js中引入即可

module.exports = function (shipit) {
  require('your-plugin')(shipit);
  shipit.initConfig({
      ...
  });
};

四、与脚本结合使用

那么,是不是定制了插件就完全不用脚本文件了呢,不一定,脚本文件有其好处,我们也可以很简单的把你现有的脚本加入自动化流程中。

只要把do_something.js中的cmd替换为执行你的脚本即可,例如:

var cmd = ‘cd /path/to/script; sh script.sh’; // 执行一个脚本文件


五,不仅仅是nodejs

既然我们可以使用shipit-deploy来实现同步代码,用插件和脚本来完成启动等额外工作,那shipit-deploy就不仅仅可以部署nodejs的项目,其他语言的项目也可以按照这个套路来实现自动化的部署。近日,本人就成功的使用shipit-cli/shipit-deploy实现了一个php的项目的自动化部署。 为了尽量少的影响 非nodejs 的项目,最好把shipit-cli和shipit-deploy全局安装。

17 回复

.NET 可以考虑用这个 shipit-mono ^_^

好文要顶😄

不懂,但是我收藏了

其实还可以继续改进,比如:

  • 支持分支
  • 支持pipeline

其实我前段时间尝试gitlab+docker,做测试、然后build、部署,还挺顺滑的…

@luoyjx 目前就支持分支,我在shipitfile.js中补上了。gitlab+docker目前也在用。

可以转载到【Node全栈】公众号么?

@i5ting 可以转载,希望跟更多人分享。

本质上来说, 就是通过ssh 远程操作多服务器(可配置), 可以执行本地 脚本文件, 并自动化此过程

shipit staging deploy 找不到命令?

@dlyt 你看一下官方文档https://www.npmjs.com/package/shipit-cli,有两种安装方式,你可以选择全局安装。

报错提示 怎么设置呢? 服务器上npm是没问题的

Running 'do_something' task...
Running "cd /tmp/deploy_to/current; npm install" on host "ht.asdasd.com".
@hasd.com-err bash: npm: command not found
'do_something' errored after 351 ms
Error: Command failed: ssh -i /Users/zxcfasd/.ssh/id_rsa [email protected] "cd /tmp/deploy_to/current; npm install"
bash: npm: command not found

我知道问题出在哪了,服务器上的node是用nvm下载的。我换台服务器正常安装的node就不会出现这个问题。 这就有一个问题,默认的路径应该是 /usr/bin/npm 但是我想换成 /root/.nvm/v6.2.0/bin/npm 怎么搞呢?

strong -pm 一键部署N台服务器

回到顶部